Should work with PowerShell versions 2 and up (tested with: 2, 3, 4).
The end result should be a pretty awesome enterprise PowerShell remoting test tool. I have used it against close to 4000 servers in one go, and it performed admirably. It should process a few hundred servers (100-500?) per minute normally. Beware of periodically potentially high CPU usage on the server that runs the script - multiple cores recommended.I thought about enforcing order of properties, but it's just three simple properties, so I might put it off for a good while. The properties returned are ComputerName (string), Success ($true if it worked, $null on error, should have made it a bool), and Error (string). Happy Select-Objecting for output order.
Here it is running in my lab environment:
Earlier versions (if any):
Test-PSRemoting.ps1.txt
Process the results. You need PowerShell v3 or up to use -WarningVariable.
Look at everything in Out-GridView (ogv):
<# .SYNOPSIS Check remote target computers for PowerShell remoting capabilities. Uses runspaces for concurrency. Copyright (C) 2015, Svendsen Tech All rights reserved. Author: Joakim Borger Svendsen .EXAMPLE .\Test-PSRemoting.ps1 -ComputerName $Servers -Credential $mycred .EXAMPLE .\Test-PSRemoting.ps1 -ComputerName $Servers | Format-Table -AutoSize .EXAMPLE $Results = .\Test-PSRemoting.ps1 -ComputerName $Servers #> [CmdletBinding()] param( # Target computer names. [Parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Mandatory=$true)][Alias('Cn', 'Hostname', 'PSComputerName')] [string[]] $ComputerName, # Prompt for credentials to be used when connecting. [switch] $PromptForCredentials, # Supply PSCredentials object to be used when connecting. [System.Management.Automation.Credential()] $Credential = [System.Management.Automation.PSCredential]::Empty, # Number of simultaneously running threads. [int] $ThrottleLimit = 32, # Do not display progress using Write-Progress. [switch] $HideProgress, # Timeout in seconds. [int] $Timeout = 30, # Don't display end summary showing start and end time using Write-Host. [switch] $Quiet ) begin { $MyEAP = 'Stop' $ErrorActionPreference = $MyEAP $StartTime = Get-Date if ($PromptForCredentials) { $Credential = Get-Credential } $RunspaceTimers = [HashTable]::Synchronized(@{}) $Runspaces = New-Object -TypeName System.Collections.ArrayList $RunspaceCounter = 0 Write-Verbose -Message 'Creating initial session state.' $ISS = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault() $ISS.Variables.Add((New-Object -TypeName System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList 'RunspaceTimers', (Get-Variable -Name 'RunspaceTimers' -ValueOnly), '')) Write-Verbose -Message 'Creating runspace pool.' $RunspacePool = [System.Management.Automation.Runspaces.RunspaceFactory]::CreateRunspacePool(1, $ThrottleLimit, $ISS, $Host) $RunspacePool.ApartmentState = 'STA' $RunspacePool.Open() # This is the script block that is run for each computer. $ScriptBlock = { [CmdletBinding()] param( [string] $Computer, [int] $ID, $Credential ) # Get the start time. $RunspaceTimers.$ID = Get-Date # The objects returned here are passed to the host... if (-not (Test-Connection $Computer -Count 1 -Quiet)) { New-Object psobject -Property @{ ComputerName = $Computer Success = $null Error = 'No ping reply' } continue } $IcmHash = @{ ErrorAction = 'Stop' ComputerName = $Computer ScriptBlock = { 'It works' } } if ($Credential.Username -ne $null) { $IcmHash.Credential = $Credential } try { $Result = Invoke-Command @IcmHash } catch { New-Object psobject -Property @{ ComputerName = $Computer Success = $null Error = $_ } continue } # Check if results are as expected. if ($Result -ne 'It works') { New-Object psobject -Property @{ ComputerName = $Computer Success = $null Error = 'Unknown error' } continue } # Everything went well, return success object. New-Object psobject -Property @{ ComputerName = $Computer Success = $true Error = $null } } # end of script block function Get-PSRemotingResult { [CmdletBinding()] param( [switch]$Wait ) do { $More = $false foreach ($Runspace in $Runspaces) { $StartTime = $RunspaceTimers[$Runspace.ID] if ($Runspace.Handle.IsCompleted) { Write-Verbose -Message ('Thread done for {0}' -f $Runspace.IObject) $Runspace.PowerShell.EndInvoke($Runspace.Handle) $Runspace.PowerShell.Dispose() $Runspace.PowerShell = $null $Runspace.Handle = $null } elseif ($Runspace.Handle -ne $null) { $More = $true } if ($Timeout -and $StartTime) { if ((New-TimeSpan -Start $StartTime).TotalSeconds -ge $Timeout -and $Runspace.PowerShell) { Write-Warning -Message ('Timeout {0}' -f $Runspace.IObject) $Runspace.PowerShell.Dispose() $Runspace.PowerShell = $null $Runspace.Handle = $null } } } if ($More -and $PSBoundParameters['Wait']) { Start-Sleep -Milliseconds 100 } foreach ($Thread in $Runspaces.Clone()) { if (-not $Thread.Handle) { Write-Verbose -Message ('Removing {0} from runspaces' -f $Thread.IObject) $Runspaces.Remove($Thread) } } if (-not $HideProgress) { $ProgressSplatting = @{ Activity = 'Testing PSRemoting capabilities' Status = 'Processing: {0} of {1} total threads done' -f ($RunspaceCounter - $Runspaces.Count), $RunspaceCounter PercentComplete = ($RunspaceCounter - $Runspaces.Count) / $RunspaceCounter * 100 } Write-Progress @ProgressSplatting } } while ($More -and $PSBoundParameters['Wait']) } # end of Get-PSRemotingResult } # end of begin block process { foreach ($Computer in $ComputerName) { $RunspaceCounter++ $psCMD = [System.Management.Automation.PowerShell]::Create().AddScript($ScriptBlock) [void] $psCMD.AddParameter('ID', $RunspaceCounter) [void] $psCMD.AddParameter('Computer', $Computer) [void] $psCMD.AddParameter('Credential', $Credential) [void] $psCMD.AddParameter('Verbose', $VerbosePreference) $psCMD.RunspacePool = $RunspacePool Write-Verbose -Message "Testing PSRemoting capabilities: Checking $Computer" [void]$Runspaces.Add(@{ Handle = $psCMD.BeginInvoke() PowerShell = $psCMD IObject = $Computer ID = $RunspaceCounter }) Get-PSRemotingResult } } end { Get-PSRemotingResult -Wait if (-not $HideProgress) { Write-Progress -Activity 'Testing PSRemoting capabilities' -Status 'Done' -Completed } Write-Verbose -Message 'Closing runspace pool.' $RunspacePool.Close() $RunspacePool.Dispose() if (-not $Quiet) { Write-Host -ForegroundColor Green ('Start time: ' + $StartTime) Write-Host -ForegroundColor Green ('End time: ' + (Get-Date)) } }Powershell Windows All Categories
Minimum cookies is the standard setting. This website uses Google Analytics and Google Ads, and these products may set cookies. By continuing to use this website, you accept this.