Enable WinRM Remotely

Usage:
enableWinRm ‘RemoteServer’ get-credential

$remoteComputer='REMOTESERVER'
$winRmPort=5985
$adminCredential=get-credential

function enableWinRm($remoteComputer,$winRmPort=5985,$adminCredential){
    function Check-NetConnection($computername,$port,$timeout=200,$verbose=$false) {
            $tcp = New-Object System.Net.Sockets.TcpClient;
            try {
                $connect=$tcp.BeginConnect($computername,$port,$null,$null)
                $wait = $connect.AsyncWaitHandle.WaitOne($timeout,$false)
                if(!$wait){
                    $null=$tcp.EndConnect($connect)
                    $tcp.Close()
                    if($verbose){
                        Write-Host "Connection Timeout" -ForegroundColor Red
                        }
                    Return $false
                }else{
                    $error.Clear()
                    $null=$tcp.EndConnect($connect) # Dispose of the connection to release memory
                    if(!$?){
                        if($verbose){
                            write-host $error[0].Exception.Message -ForegroundColor Red
                            }
                        $tcp.Close()
                        return $false
                        }
                    $tcp.Close()
                    Return $true
                }
            } catch {
                return $false
            }
    }
    if (!(get-command psexec)){
        # Install Chocolatey
        if (!(Get-Command choco.exe -ErrorAction SilentlyContinue)) {
            [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;
            Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
            }
        choco install sysinternals -y;  
        }
    $success=check-netconnection $remoteComputer $winRmPort
    write-host 'Attempting to use psexec to enable WinRM remotely...'
    if(!$adminCredential -and !$success){ # Enable WinRM Remotely
        $null=psexec.exe \\$remoteComputer -s C:\Windows\system32\winrm.cmd qc -quiet; 
    }elseif(!$success){
        $username=$adminCredential.Username
        $password=$adminCredential.GetNetworkCredential().Password
        $null=psexec.exe \\$remoteComputer -u $username -p $password -s C:\Windows\system32\winrm.cmd qc -quiet
    }else{
        write-host "WinRm is already available on $remoteComputer" -ForegroundColor Green
    }
    return check-netconnection $remoteComputer $winRmPort
}

enableWinRm $remoteComputer $winRmPort $adminCredential
# Deprecated version

function enableWinRm($remoteComputer,$winRmPort){
    function Check-NetConnection($computername, $port) {
        $session = New-Object System.Net.Sockets.TcpClient;
        try {
            $session.Connect($computername, $port=5985);
            $true;
        } catch {
            $false;
        } finally {
            $session.Close();
        }
    }
    if (!(get-command psexec)){
        # Install Chocolatey
        if (!(Get-Command choco.exe -ErrorAction SilentlyContinue)) {
            [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;
            Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
            }
        choco install sysinternals -y;  
        }
    $success=check-netconnection $remoteComputer $winRmPort
    psexec.exe \\$remoteComputer -s C:\Windows\system32\winrm.cmd qc -quiet; # Enable WinRM Remotely
    return check-netconnection $remoteComputer $winRmPort
}

Previous versions:

# Enable-WinRM-Remotely.ps1

# Set variables
$remoteHost="192.168.500.1"
$adminUsername="Administrator";

# Autogen variables
$trustedHosts=$([void]($remoteHost -match "(.*)\.");$matches[1])+".*" # Assuming class C - I'll work on auto detection of netmask later
$adminCredential=get-credential -UserName $adminUsername -Message "Enter password for account $adminUsername";

function computerIsDomainJoined{
    if ((gwmi win32_computersystem).partofdomain -eq $true) {
    write-host -fore green "$ENV:computername is domain joined!"
    return $true;
    } else {
        write-host -fore red "$ENV:computername is on a workgroup!"
        return $false;
        }
}

function installPrerequisitesOnLocalhost{
    if(!(get-command psexec -ErrorAction SilentlyContinue)){
        if (!(Get-Command choco.exe -ErrorAction SilentlyContinue)) {
            Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
            }
        choco install sysinternals -y
        }
    }

function addWinRmTrustedHosts{
    param($trustedHosts)
    Write-Host "Adding $trustedHosts as trusted on $env:computername..."
    winrm quickconfig -force|out-null;
    $addTrustedHostsLocal="winrm set winrm/config/client '@{TrustedHosts=`"$trustedHosts`"}'";
    invoke-expression $addTrustedHostsLocal;
}

function enableWinRmRemotely{
    Param(
        [string]$computername,
        [PScredential]$adminCredential,
        [string]$trustedHosts
        )
    # Extract password from credential
    $adminUsername=$adminCredential.Username;
    $adminPassword=$adminCredential.GetNetworkCredential().Password;

    # Test to see if WinRM is indeed installed
    Write-Host "Checking $computername..."    
    $winRmPortOpen=test-netconnection $computername -port 5985 -InformationLevel Quiet
    
    if($winRmPortOpen){
        $session=New-PSSession $computername -Credential $adminCredential -ea SilentlyContinue;
        }else{
            write-host "Port 5985 is not open on $computername";
            return $false;
            }

    if (!($session)){
        # Adding psexec on localhost to perform the next tasks        
        installPrerequisitesOnLocalhost;

        # Ensuring the psexec ports are open
        $port135Open=test-netconnection $computername -port 135 -InformationLevel Quiet
        $port445Open=test-netconnection $computername -port 445 -InformationLevel Quiet
        if ($port135Open -and $port445Open){
            # Base command: psexec.exe \\$computername -u $adminUsername -p $adminPassword -s C:\Windows\system32\winrm.cmd qc -quiet;
            $process=Start-Process -FilePath "psexec.exe" -ArgumentList "\\$computername -u $adminUsername -p $adminPassword -s C:\Windows\system32\winrm.cmd qc -quiet;" -PassThru;        
            if ($process.ExitCode -ne 0){
                write-host "PSExec has failed.";
                return $false;
                }else{
                    write-host "PSExec has succeeded.";
                    
                    if (computerIsDomainJoined){
                        write-host "This computer is joined to a domain. Kerberos Authentication will be the default.";
                        }else{
                        write-host "This computer is not joined to a domain. Trusted Host must be set in lieu of Kerberos Authentication.";
                        
                        # Ensure that localhost trusts remote hosts
                        $localTrustedHosts=(Get-item wsman:\localhost\Client\TrustedHosts).Value
                        if ($localTrustedHosts -notcontains $trustedHosts){
                            addWinRmTrustedHosts -trustedHosts $trustedHosts;
                            }
                        
                        # Settting trusted host on remote computer to enable WinRM authentication
                        # psexec.exe \\$computername -u $adminUsername -p $adminPassword -s winrm set winrm/config/client '@{TrustedHosts="192.168.2.*"}'
                        $addTrustedHostsRemote="psexec.exe \\$computername -u $adminUsername -p $adminPassword -h -d powershell.exe 'set-item WSMan:\localhost\Client\TrustedHosts -Value $trustedHosts -force'"
                        Invoke-Expression $addTrustedHostsRemote;
                        }
                    
                    return $true;
                    }        
            }else{
                write-host "Please check port 135 & 445 ingress on $computername";
                return $false;
                }
        }else{
            Write-Host "WinRM has been already enabled. No changes to WinRM have been made.";
            remove-pssession $session;
            return $true;
            }    
}

enableWinRmRemotely -computername $remoteHost -adminCredential $adminCredential -trustedHosts $trustedHosts

Old version:

# Set variables
$server="SHERVER007"

# Enable WinRM Remotely
psexec.exe \\$remoteHost -s C:\Windows\system32\winrm.cmd qc -quiet
# Invoke-WmiMethod -ComputerName $server -Class Win32_Process -Name Create -ArgumentList "C:\Windows\system32\winrm.cmd -q"

# Test to see if WinRM is indeed installed
test-netconnection $remoteHost -port 5985

# Enter PowerShell session on remote host
enter-pssession $remotehost

function enableRemoteWinRM{
  Param([string]$computername)

  Write-Host "checking $computername..."

  function pingTest{
      Param([string]$node)
      try{
        Return Test-Connection $node -Count 1 -Quiet -ea Stop;
      }
      catch{Return $False}
    }

  if (pingTest $computername){
      if (!(Test-WSMan $computername -ea SilentlyContinue)){
        if(!(get-command psexec)){
            if (!(Get-Command choco.exe -ErrorAction SilentlyContinue)) {
                Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
                }
            choco install sysinternals -y
            }
        psexec.exe \\$computername -s C:\Windows\system32\winrm.cmd qc -quiet
        }else{Write-Host "WinRM has been already enabled. No changes to WinRM have been made."}
    }
  Else{Write-Host "Unable to determine if WinRM is enabled on $computername`.`n Ping test has failed. Check if this computer is online and whether there's a firewall blocking of ICMP";}
}

Leave a Reply

Your email address will not be published. Required fields are marked *