Posted On December 4, 2020

PowerShell: connectWinRM Function to Create New-PSSession

kimconnect 0 comments
blog.KimConnect.com >> Codes >> PowerShell: connectWinRM Function to Create New-PSSession

This reusable function may be included into PoSh scripts for better connection toward Windows machines via WinRM.

function connectWinRm($computer,$adminCredential=$false,$winRmPort=5985){
    if(!$computer){
        write-warning "Computer name must be specified to initiate a WinRM connection."
        return $false
    }
    # Legacy equivalent to Test-Netconnection
    function checkNetConnection($computername,$port,$timeout=1000,$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
        }
    }
    function enableWinRmRemotely($remoteComputer,$winRmPort,$adminCredential){
        function Check-NetConnection($computername,$port,$timeout=1000,$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 -ea SilentlyContinue)){
            # 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;  
            }            
        write-host 'Attempting to use psexec to enable WinRM remotely...'
        if(!$adminCredential){ # Enable WinRM Remotely
            $null=psexec.exe \\$remoteComputer -s C:\Windows\system32\winrm.cmd qc -quiet; 
        }else{
            $username=$adminCredential.Username
            $password=$adminCredential.GetNetworkCredential().Password
            $null=psexec.exe \\$remoteComputer -u $username -p $password -s C:\Windows\system32\winrm.cmd qc -quiet
            }
        return check-netconnection $remoteComputer $winRmPort
    }

    # If machine is not pingable, wait five minutes
    $fiveMinuteTimer=[System.Diagnostics.Stopwatch]::StartNew()
    do{
        $ping = Test-Connection $computer -quiet
        if($ping -eq $false){sleep 1}
        $pastFiveMinutes=$fiveMinuteTimer.Elapsed.TotalMinutes -ge 5
    }until ($ping -eq $true -or $pastFiveMinutes)
    $fiveMinuteTimer.stop()

    $winRmAvailable=checkNetConnection $computer $winRmPort
    if(!$winRmAvailable){
        write-host "Attempting to enable WinRM on $computer" -ForegroundColor Yellow
        $enableWinRmSuccessful=enableWinRmRemotely $computer
        if($enableWinRmSuccessful){
            write-host "WinRM enabled: $enableWinRmSuccessful"
        }else{
            write-warning "WinRM could not be enabled remotely. WinRM connection aborted."
            return $false
            }
    }
    # Wait for WinRm session prior to proceeding
    #if($session.state -eq 'Opened'){remove-pssession $session}
    do{
        $session=if($adminCredential){
            try{
                New-PSSession -ComputerName $computer -Credential $adminCredential -ea Stop
            }catch{
                New-PSSession -ComputerName $computer -Credential $adminCredential -SessionOption $(new-pssessionoption -IncludePortInSPN)
            }
        }else{
            try{
                New-PSSession -ComputerName $computer -ea Stop
            }catch{
                New-PSSession -ComputerName $computer -SessionOption $(new-pssessionoption -IncludePortInSPN)
            }
        }
        #sleep -seconds 1
        if ($session){
            write-host "Connected to $computer."
            return $session
        }
    } until ($session.state -match "Opened")    
}

Leave a Reply

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

Related Post

Centos 5.3 Server preparation for web hosting

These are compatible Repositories: FreshRPMS, Dries, NewRPMS and PlanetCCRMA   Note: to update PHP and…

GPO Logon Banner

Update: this information is outdated. Use this link for the current method of creating Logon…

WinRM Management Consideration

Infrastructure needs to be able to leverage scripting automation to perform Vulnerability Remediation, Resource Provisioning,…