-
Notifications
You must be signed in to change notification settings - Fork 4
Remote
PowerShell uses WinRM based on WS-Management Protocol providing a wide range of security settings.
By default remote management is disabled. After remote management enabling, without rights tuning, connections will be allowed for anyone to anywhere. Important to know that computers should be join to domain and elevated right required.
For configuration could be used next tool winrm Example: winrm quickconfig
PowerShell cmdlet equivalent PSRemoting Example: Enable-PSRemoting -Force
Configuration in the domain could be done with Group policy: winrm GPO configuration
Cmdlet for connection to the remote PC Connection procedure is quite lengthy itself (compared to other language procedures) Therefore, where several successive operations on remote PCs required, then the logic should be built on PSSession in terms of performance
There much more connection settings available when used Sessions comparing with using -ComputerName parameter for Invoke-Command or Enter-PSSession There is a good practice remove remote sessions when they are not needed anymore. For that used Remove-PSSession cmdlet
Example: You need to get processors from all PCs in the domain, then check against the list of available processors for replacement When you get the comparison list, run a diagnostic script on PC with the required processors The solution of the example may be as follows:
$CompatibleCPUs = Import-CSV "C:\Work Documents\CPUs.csv"
$Computers = Import-CSV "C:\Work Documents\DomainComputers.csv"
$PoShSession = New-PSSession -ComputerName $Computers
$result = Invoke-Command -Session $PoShSession -ScriptBlock {
[psobject]@{
ComputerName = $Env:ComputerName
ProcessorName = Get-CimInstance win32_processor | select -ExpandProperty name
}
}
$DiagnosticNeeded = ($result | Where-Object {$CompatibleCPUs.Name -contains $_.ProcessorName}).ComputerName
$PoShSession = $PoShSession | Where-Object {$_.Computername -in $DiagnosticNeeded}
Invoke-Command -Session $PoShSession -ScriptBlock {
. \\SMBServer1\DomainScripts\DiagnosticScript.ps1
}
Remove-PSSession $PoShSessionServes for non-interactive command execution on remote host (operations not allowed user interaction)
Parameter accept computer name or IP address, or their list.
- Example 1 – the command will be executed on each PC 1 by 1. With a large number of iterations this will increase the command execution time.
- Example 2 is preferable.
# Example 1
Get-ADComputer -Filter * | Foreach {
# ScriptBlock will be executed on each PC >sequently<
Invoke-Command -ComputerName $_.Name -ScriptBlock {$Env:ComputerName}
} # Example 2
# $ADComputers will list all PCs in the domain
$ADComputers = (Get-ADComputer -Filter *).Name
# ScriptBlock will be executed on all computers from $ADComputers list >simultaneously<
Invoke-Command -ComputerName $ADComputers -ScriptBlock {$Env:ComputerName}Used [PSSession] object as an input produced by New-PSSession cmdlet
$ADComputers = (Get-ADComputer -Filter *).Name
$PoShSession = New-PSSession -ComputerName $ADComputers
Invoke-Command -Session $PoShSession -ScriptBlock {$Env:ComputerName}ScriptBlock part of code stored in curly brackets.
{ Get-Command Invoke-Command }Importan note, that content of code block is not executed without external command that can do that. Codeblock can be compared with function - function declaration and function execution is 2 different actions.
$ScrBlock = { $Env:ComputerName }Parameter -ScriptBlock accept code framed by curly brackets, same as variable contained [ScriptBlock]
# Example
$Computers = @('ComputerA','ComputerB','ComputerC')
$ScrBlock = {
Write-Output "You are connected to $ENV:ComputerName"
$scrPath = '\\SMBServer1\DomainScripts\DiagnosticScript.ps1'
Write-Output "Starting diagnostic script : $scrPath"
$result = . $scrPath
If ($result.Status -eq 'Succeed'){
return $true
} Else {
return $false
}
}
Invoke-Command -ComputerName $Computers -ScriptBlock $ScrBlockAllows running the execution of commands on remote PCs in separate processes and by default does not block further script execution Example:
$Computers = '127.0.0.1'
$ScrBlock = {
Start-Sleep 5
return 'Some actions A'
}
Invoke-Command -ComputerName $Computers -ScriptBlock $ScrBlock -AsJob
# Here a part of script can be executed that does not interfere with the execution of $ScrBlock
'Some other actions B'
# Job commandlets are available if there is a need to wait for the execution of $ScrBlock
$Jobs = Get-Job
$Jobs | Wait-Job -Timeout 60
$Jobs | Receive-Job
$Jobs | Remove-Job -ForceServes for interactive execution of commands. ComputerName and Session parameters work in the same way.