PS Remoting
Remoting
Default Ports for PS Remoting
TCP/5985 = HTTP
TCP/5986 = HTTPS
Enable-PSRemoting
Store Credentials
#Store Password run once to export password read-host -assecurestring | convertfrom-securestring | out-file C:\securestring.txt
$username = "domain01\serviceaccount" $password = cat C:\securestring.txt | convertto-securestring $cred = new-object -typename System.Management.Automation.PSCredential ` -argumentlist $username, $password
$SecureStringPath = "C:\scripts\securestring.txt" $Key = (95,183,225,42,45,40,195,199,49,22,148,13,57,155,79,172,27,133,163,198,234,54,236,94,168,50,44,207,197,78,146,226) #Store Password #read-host -assecurestring | convertfrom-securestring -Key $Key | out-file C:\scripts\securestring.txt $username = "blah\testServiceAccount" $password = cat $SecureStringPath | convertto-securestring -Key $Key $Cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $password
$RSession = New-PSSession -ComputerName Server -Credential $cred
Invoke-Command -Session $RSession -ScriptBlock {Get-WmiObject -Class Win32_LogicalDisk}
Multi-hop support with credssp
#need to enable CredSSP (multi-hop support) in order for this to work #Enable-WSManCredSSP -Role Server #Enable-WSManCredSSP -Role Client -DelegateComputer SourceServerName http://dustinhatch.tumblr.com/post/24589312635/enable-powershell-remoting-with-credssp-using-group
Testing Remoting
$cred = Get-Credential $Servers = "server1","server2" foreach ($Server in $Servers) { $TestPSRemoting = $null $TestPSRemoting = Test-WSMan -Credential $cred -Authentication Negotiate -ComputerName $Server If ($TestPSRemoting) { Write-Host "$Server connected successfully" } Else {Write-Host "$Server connection failed"} }
Using Remoting
Interactively connecting to a remote server
Enter-PSSession SERVER1 [SERVER1]: PS C:\> $Session = New-PSSession -ComputerName SERVER1 Enter-PSSession -Session $Session
running commands against a remote server (or array of servers)
Invoke-Command –ComputerName server1, server2, server3 –ScriptBlock { iisreset } Invoke-Command –ComputerName (Get-Content Servers.txt) ScriptBlock { iisreset } Invoke-Command –ComputerName $servers ScriptBlock { iisreset } $Results = Invoke-Command -Session $Session -ScriptBlock { Get-Service }
Scriptblock variable using Here-string
$Command = [ScriptBlock]::Create(@" Import-Module ActiveDirectory Do some stuff "@)
Implicit Remoting
Need some cmdlets that are not installed on your machine, not a problem you can use them through ps remoting
Open a Windows PowerShell session to the server that has the snappin / module that you want
Use Invoke-Command to import the module you want into the session
Run Import-PSSession to connect to the remote module
Now you can run the cmdlets like they are local
$Session = New-PSSession –ComputerName SERVER1 Invoke-Command –Session $Session –ScriptBlock {Import-Module ActiveDirectory} Import-PSSession –Session $Session –Module ActiveDirectory
Passing Variables
Invoke-Command -ComputerName Server01 -ScriptBlock { Write-Output "The value of `$a is: $($args[0])" Write-Output "The value of `$b is: $($args[1])" } -ArgumentList $a,$b Invoke-Command -ComputerName Server01 -ScriptBlock { param ($first,$second) Write-Output "The value of `$a is: $first" Write-Output "The value of `$b is: $second" } -ArgumentList $a,$b
In PowerShell 3.0 we can simply use the Using scope modifier followed by a colon and the name of the local variable we want to reference:
Invoke-Command -ComputerName Server01 -ScriptBlock { Write-Output "The value of `$a is: $using:a" Write-Output "The value of `$b is: $using:b" }