In my quest to make my life easier, I have been waiting with bated breath to get my hands on the remoting features of PS v2. Now that I have access to windows 7 and Windows Server 2008 R2, let the fun begin!
When looking for information about these new features, where better to go than the source. I found this video on Tech.ED where Jeffery Snover (Powershell Godfather as he is introduced!) co presents using Powershell v2 in large Environments.
From my findings (mainly from this video) there are primarily 2 new ways of gathering information from remote computers in PS v2, the all singing all dancing big brother that needs all the options installed and configured, and the little brother version which has less pre-requisites for the remote client, but does not do quite as much.
The -computername switch (Little Brother)
One of the biggest things missing in powershell 1 was the ability to run a cmdlet agains a remote machine. With PS v2 this has changed. Suddenly, I can get the event logs from my DC from my workstation without too much fuss :
This will get information from Server 2003, Server 2008 as well as 2008 R2 so very useful while there is a wait for either all computers that you manage become windows 7 or 2008 R2 or PS v2 becomes available for the earlier OS's.
Sessions and jobs (All Singing All dancing Big Brother)
When you have your server estate (and workstations too) to PS v2, nice things become available.
The key components to Remoting are as follows :
WinRM service on the Remote Computer.
The service needs to be running and actively listening for connections. The simplest way of configuring this is running 'winrm qc' at an elevated command prompt.
winrm qc does the following :
set the winrm service to auto start
start the service
create a winrm listener
add firewall exceptions to allow the service to communicate.
Powershell v2 installed
To process the commands, PS v2 need to be installed on the remote machine. (no real suprise there really!)
Permissions!
Even if you are a local admin on the server, you need to be part of the Remote Desktop Users group on the server. It does seem a bit weird as you are not actually logging in interactivly, but I can only assume it assigns a range of remote access permissions (assuming is a dangerous thing I know - I will try to find out what exact permission is required).
I started with the idea that I would have to manage all my jobs independantly of each other. By this i mean start all jobs seperatly, check to see if all jobs are still running and once all complete, get the results.
Here's what I created :
Define the commands that you want to run on the remote host
$sb = [scriptblock]{ipconfig;get-service}
Run the command using invoke command
$store.job = Invoke-command -computername $Computer -scriptblock $sb -asjob
Grab the results
$col.return = receive-job $col.job -keep
After setting up the inital script block - ie the commands that you want to run on the remote machine, I set up individual jobs for each computer in the array and stored them in my $store Array
The while loop then checked the job status for all jobs, and when all complete, output all the results.
I was infact quite proud of this, until I found out that PowerShell can do all this for you!
Remoting script version 2.
Thats a bit cleaner, Ta very much Mr Snover! Heres the same script with comments :
You can add -throttle to the invoke-command cmdlet to limit the ammount of jobs that are run at once. EG : invoke-command -computername $ComputerArray -scriptblock $sb -asjob -throttle 3
Instead of using a scriptblock, you can use any local ps1 file. Here is the same code using a file as the source code :
If you don't use the -keep option for receive-job, the results are purged (deleted) from the job
To be clean and tidy, add $job | remove-job when finished
That's about as far as i have got with remoting, just got to wait for PowerShell v2 to be available on all my OS's!
When looking for information about these new features, where better to go than the source. I found this video on Tech.ED where Jeffery Snover (Powershell Godfather as he is introduced!) co presents using Powershell v2 in large Environments.
From my findings (mainly from this video) there are primarily 2 new ways of gathering information from remote computers in PS v2, the all singing all dancing big brother that needs all the options installed and configured, and the little brother version which has less pre-requisites for the remote client, but does not do quite as much.
The -computername switch (Little Brother)
One of the biggest things missing in powershell 1 was the ability to run a cmdlet agains a remote machine. With PS v2 this has changed. Suddenly, I can get the event logs from my DC from my workstation without too much fuss :
get-eventlog -ComputerName dc01 -logname "Directory Service" -Newest 5.
This will get information from Server 2003, Server 2008 as well as 2008 R2 so very useful while there is a wait for either all computers that you manage become windows 7 or 2008 R2 or PS v2 becomes available for the earlier OS's.
Sessions and jobs (All Singing All dancing Big Brother)
When you have your server estate (and workstations too) to PS v2, nice things become available.
The key components to Remoting are as follows :
WinRM service on the Remote Computer.
The service needs to be running and actively listening for connections. The simplest way of configuring this is running 'winrm qc' at an elevated command prompt.
winrm qc does the following :
set the winrm service to auto start
start the service
create a winrm listener
add firewall exceptions to allow the service to communicate.
Powershell v2 installed
To process the commands, PS v2 need to be installed on the remote machine. (no real suprise there really!)
Permissions!
Even if you are a local admin on the server, you need to be part of the Remote Desktop Users group on the server. It does seem a bit weird as you are not actually logging in interactivly, but I can only assume it assigns a range of remote access permissions (assuming is a dangerous thing I know - I will try to find out what exact permission is required).
I started with the idea that I would have to manage all my jobs independantly of each other. By this i mean start all jobs seperatly, check to see if all jobs are still running and once all complete, get the results.
Here's what I created :
$sb = [scriptblock]{ipconfig;get-service}I won't go into too much detail about this as there is a much better way script coming up. But the key lines are as follows:
$collection = @()
$ComputerArray = "dc01","dc02"
foreach ($Computer in $ComputerArray){
$store = "" | select "name","job","return"
$store.name = $Computer
$store.job = Invoke-command -computername $Computer -scriptblock $sb -asjob
$collection += $store
}
$count = 0
:main while ($collection.length -gt $count){
foreach ($col in $collection){
if ($col.return -eq $null){
switch ($(get-job $col.job.name).state){
"Completed" {$col.return = receive-job $col.job -keep;$count++;if ($collection.length -eq $count){break main}}
"Failed" {$col.return = "job failed";$count++;if ($collection.length -eq $count){break main}}
}
}
}
"waiting 5 seconds"
Start-Sleep 5
}
foreach ($col in $collection){
$col.return
}
Define the commands that you want to run on the remote host
$sb = [scriptblock]{ipconfig;get-service}
Run the command using invoke command
$store.job = Invoke-command -computername $Computer -scriptblock $sb -asjob
Grab the results
$col.return = receive-job $col.job -keep
After setting up the inital script block - ie the commands that you want to run on the remote machine, I set up individual jobs for each computer in the array and stored them in my $store Array
The while loop then checked the job status for all jobs, and when all complete, output all the results.
I was infact quite proud of this, until I found out that PowerShell can do all this for you!
Remoting script version 2.
$sb = [scriptblock]{ipconfig;get-service}
$ComputerArray = "dc01","dc02"
$Job = invoke-command -computername $ComputerArray -scriptblock $sb -asjob
$Job.childjobs
$Job | wait-job
$results = receive-job $Job -keep
$results
Thats a bit cleaner, Ta very much Mr Snover! Heres the same script with comments :
#Set up the commands you want to runSome notes
$sb = [scriptblock]{ipconfig;get-service}
#setup the list of servers you want to target
$ComputerArray = "dc01","dc02"
#run the invoke-command as a job on the whole array. This creates 1 job with multiple child jobs
$Job = invoke-command -computername $ComputerArray -scriptblock $sb -asjob
#view those child jobs
$Job.childjobs
#wait for all the child jobs to complete
$Job | wait-job
#get all the results in one go
$results = receive-job $Job -keep
#display results
$results
You can add -throttle to the invoke-command cmdlet to limit the ammount of jobs that are run at once. EG : invoke-command -computername $ComputerArray -scriptblock $sb -asjob -throttle 3
Instead of using a scriptblock, you can use any local ps1 file. Here is the same code using a file as the source code :
$script = "c:\scripts\example.ps1"
$ComputerArray = "dc01","dc02"
$Job = invoke-command -computername $ComputerArray -filepath $script -asjob
$Job.childjobs
$Job | wait-job
$results = receive-job $Job -keep
$results
If you don't use the -keep option for receive-job, the results are purged (deleted) from the job
To be clean and tidy, add $job | remove-job when finished
That's about as far as i have got with remoting, just got to wait for PowerShell v2 to be available on all my OS's!
Comments
Post a Comment