Question

I'm running into some issues with the WinRM service. It constantly insists on being a "delayed start (automatic)" service instead of just "automatic".

Why? This is causing issues for my VMs (on Hyper-V). I revert them programatically by PowerShell and then need to access them via PowerShell remoting but sometimes the WinRM service just isn't started yet when I first bring the VMs online (they are "fully booted", as in I can log into them).

If I set the service to automatic anyway, running the PowerShell command winrm quickconfig says that the service is NOT set up for remoting and insists on setting the service back to delayed start.

How can I ensure that the Windows RM service is running before I attempt to open a remote PowerShell session?

Was it helpful?

Solution

A basic reasoning about why certain services might be loaded after the boot process (Delayed Start) would be:

  1. To improve the boot performance of server and has some security benefits.

  2. Certain services depend on other services to start. In the case of Windows Remote Management Service, it depends on the following services
    a. HTTP Service
    b. Remote Procedure Call (RPC) (Automatic)
    i. DCOM Server Process Launcher (Automatic)
    ii. RPC Endpoint Mapper (Automatic)

How can I ensure that the Windows RM service is running before I attempt to open a remote PowerShell session?

Take a look at the following options and functions I have written to do something you want.

A) You can use Test-Connection to check if the computer is online or not.

Test-Connection -ComputerName $Computer -Count 1 -Quiet

B) I have created function StartWinRMIfStopped that will start "WinRM" service using WMI.

C) Second function is TryToCreateNewPSSession will attempt to create a new PSSession or should give you exception object

param([string]$server)
Get-PSSession | Remove-PSSession
$newsession = $null
function StartWinRMIfStopped
{
param([string]$ComputerName)
    Write-Host $ComputerName
    $WinRMService = Get-WmiObject -Namespace "root\cimv2" -class Win32_Service -Impersonation 3 -ComputerName $ComputerName | Where-Object {$_.Name -match "WinRM"}
    if($WinRMService.State -eq "Stopped" -or $WinRMService.State -eq "Paused"){
        "WinRM Service is" + $WinRMservice.State
        $WinRMService.StartService()
    }
    else{
        "WinRM Service is " + $WinRMservice.State
    }
}
function TryToCreateNewPSSession{
    param([string]$computerName)
    Try
    {
        $newsession = New-PSSession -Computer $computerName -ErrorAction Stop    
        #Connect-PSSession -Session $newsession
        $newsession        
    }
    Catch [System.Management.Automation.RuntimeException]{    
        if($error.Exception.Gettype().Name -eq "PSRemotingTransportException"){
            Write-host "WinRM service is not started on the server"
        }
        Write-host "RuntimeException occured in creating new PSSession to the Server"
    }
    Catch [Exception]{
        Write-host "Generic Exception while creating PSSession"
    }
}

$error.Clear()
If (Test-Connection -Computer $server -count 1 -Quiet) { 
#Connection to server successfull    
StartWinRMIfStopped $server
Start-Sleep -s 4
#Invoke Command on remote server using trytocreatenewpssession function.
Invoke-Command -Session (TryToCreateNewPSSession $server) -ScriptBlock { write-host "hello world"}
}

You can invoke the whole script as

PS C:\> .\ScriptName.ps1 remotecomputername
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top