Use PowerShell
Real Admins Script
Real Admins Script
In Jeff Hicks’s Prof. PowerShell series, he continues with his tips on working with functions. He uses the Check-Service function that was in the previous article and that I provided another option in this post. Jeff describes how you can make a function act more like a cmdlet.
The problem that you run into in V1 of PoweShell is that it is easy to make your functions work with the pipeline
Function Check-Service {
Param([string]$service=”spooler” )
PROCESS
{
$wmi=get-wmiobject win32_service -filter “name=’$service’” -computername $_
if ($wmi.state -eq “running”) {
write $True
}
else {
write $False
}
}
}
Get-Content servers.txt | Check-Service
OR work well with parameters being passed in.
Function Check-Service {
Param([string[]]$server=$env:computername, [string]$service=”spooler” )
$wmi=get-wmiobject win32_service -filter “name=’$service’” -computername $server
if ($wmi.state -eq “running”) {
write $True
}
else {
write $False
}
}
Check-Service –Server Server01, Server02, Server03
Advanced functions in V2 of PowerShell can alleviate this problem (a topic for a whole new post), but a workaround I’ve found for V1 is to use the Begin block to take certain command line parameters and pass them back into the function via the pipeline.
Function Check-Service {
Param([string[]]$server=$null,[string]$service=”spooler” )
BEGIN
{
if ($server -ne $null)
{
$server | Check-Service –Service $service
}
}
PROCESS
{
if ($_ -ne $null)
{
$wmi=get-wmiobject win32_service -filter “name=’$service’” -computername $_
if ($wmi.state -eq “running”) {
write $True
}
else { write $False }
}
}
}
This enables both of the above scenarios:
Get-Content servers.txt | Check-Service
Check-Service –Server Server01, Server02, Server03
PSMDTAG:FAQ param
PSMDTAG:FAQ pipeline
Updated: (Missed a little recursion bug.. thanks Aleksandar!)
March 16, 2009 - 6:59 am
Is there a preference in doing the ‘$server | Check-Service –Service $service’ in an BEGIN block over the END block?
March 16, 2009 - 7:16 am
I can’t think of any reason off hand. I’m looking at it as an order of operations, which do I want to occur first, processing pipeline input or processing parameters being passed in from the expression.
Using the BEGIN block means I’m prioritizing the expression’s parameters, while using the END block would prioritize the pipeline input.
In most cases, you would be using the function one way or the other and this wouldn’t come in to play.
Nice point. Thanks!
March 16, 2009 - 3:40 pm
When I run it in V1:
PS>Check-Service server1
The script failed due to call depth overflow. The call depth reached 101 and the maximum is 100.
Similar thing in V2:
PS>Check-Service server1
The script failed due to call depth overflow. The call depth reached 1001 and the maximum is 1000.
+ CategoryInfo : InvalidOperation: (1001:Int32) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : CallDepthOverflow
I’ve found this looking for an error message – http://www.manning-sandbox.com/message.jspa?messageID=59410
March 17, 2009 - 5:14 am
Thanks for checking my work Aleksandar. When doing that I normally set my initial values to $null, but I left it as $env:computername, so it kept trying to pipe the computer name through the command until Powershell’s recursion limit was hit. My bad.