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

PowerShell: Replacing Characters Inside Text Files

$textFilesDirectory="C:\Users\$env:computername\Desktop\test" $textFileExtensions='.txt' $regexNewlineOnly="(?<!\r)\n$" $replaceWith="`r`n" function updateFile{ param( $file="C:\Users\$env:username\Desktop\test.txt", $regexMatch="(?<!\r)\n$", $replaceWith="`r`n", $output ) $output=if($output){$output}else{$file} if($file -ne…

How To Run Python Interactive Command Line Mode (CLI)

Windows PS C:\WINDOWS\system32> python Python 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:37:50) [MSC v.1916 64 bit…

Basic HTML and HTML5: Add a Submit Button to a Form

<h2>CatPhotoApp</h2><main><p>Click here to view more <a href="#">cat photos</a>.</p><a href="#"><img src="https://bit.ly/fcc-relaxing-cat" alt="A cute orange cat lying…