Function not working in a foreach scriptblock - works fine without the foreach loop
-
Thursday, February 21, 2013 7:28 PM
Hi everybody, I am new to the forums and new to scripting, so please bear with me. I am prepared for flames.
I built a couple of simple functions. The first one "Servicecheck" simply uses get-wmiobject to query a specific service to see if it is running or stopped. The second one "Displayinfo" uses an If-elseif to change the color of the output according to the state of the service ($Serviceinfo.state.) These functions work fine and return the proper state until I try to use them in a foreach scriptblock.
In the scriptblock when they run, it appears that $Serviceinfo never gets populated and therefore all of my services appear to be in the Unknown state.
I am probably making a nube mistake, but my head is sore from banging it against the wall.
Any help would be appreciated,
Keithdubya
CLS
$Hostname = "Server1"
Function ServiceCheck
{
get-WmiObject win32_service -Computername $Hostname | where-object {$_.name -eq $Servicename}
}
Function DisplayInfo
{
if ($Serviceinfo.state -eq "Running") { Write-Host Current State of the service $Servicename is $Serviceinfo.state }
elseif ($Serviceinfo.state -eq "Stopped") { Write-Host Current State of the service $Servicename is $Serviceinfo.state -ForegroundColor red }
else { Write-Host Current State of the service $Servicename is Unknown -ForegroundColor Yellow -BackgroundColor black }
}
$Servicenames = Get-Content c:\myscripts\services.txt
foreach($Servicename in $Servicenames) {
$Serviceinfo = Servicecheck
DisplayInfo
}
All Replies
-
Thursday, February 21, 2013 7:51 PM
You need parameters for your functions to work properly in this case:
CLS $Hostname = "Server1" Function ServiceCheck ([String]$Hostname, [String]$Servicename) { return get-WmiObject win32_service -Computername $Hostname | where-object {$_.name -eq $Servicename} } Function DisplayInfo ($Serviceinfo, [String]$Servicename) { if ($Serviceinfo.state -eq "Running") { Write-Host Current State of the service $Servicename is $Serviceinfo.state } elseif ($Serviceinfo.state -eq "Stopped") { Write-Host Current State of the service $Servicename is $Serviceinfo.state -ForegroundColor red } else { Write-Host Current State of the service $Servicename is Unknown -ForegroundColor Yellow -BackgroundColor black } } $Servicenames = Get-Content c:\myscripts\services.txt foreach($Servicename in $Servicenames) { DisplayInfo -Serviceinfo (Servicecheck -Hostname $Hostname -Servicename $Servicename) }
It seems like some basic programming training will benefit you, or your journey in scripting will be very rough.
- Edited by AverageJoeOfToronto Thursday, February 21, 2013 8:04 PM edited code
- Marked As Answer by Keithdubya Saturday, February 23, 2013 2:40 AM
-
Thursday, February 21, 2013 7:58 PMModerator
You are running into a couple of things: how to call functions and scope. You could usefully look both up using your search engine to find more about these two.
What you should be doing in the service check function is passing the name of the system you want to check. Like this:
Function ServiceCheck {
Param (
$system,
$servicename)
Get-WmiObject Win32_Service -Computername $System | where-object {$_.name -eq $Servicename}
}and
Function DisplayInfo {
Param ($ServericeName,
$ServiceInfo)If ($Serviceinfo.state -eq "Running") { Write-Host Current State of the service $Servicename is $Serviceinfo.state }
elseif ($Serviceinfo.state -eq "Stopped") { Write-Host Current State of the service $Servicename is $Serviceinfo.state -ForegroundColor red }
else { Write-Host Current State of the service $Servicename is Unknown -ForegroundColor Yellow -BackgroundColor black }
{
Then you want to do something like this:
hostname = 'Server1'
HTH
$Servicenames = Get-Content c:\myscripts\services.txt
foreach($Servicename in $Servicenames) {
$Serviceinfo = Servicecheck -System $hostname -ServiceName $servicename
DisplayInfo -ServiceName $Servicename -ServerInfo $ServiceInfo
}
Thomas Lee <DoctorDNS@Gmail.Com>
- Marked As Answer by Keithdubya Saturday, February 23, 2013 2:41 AM
-
Thursday, February 21, 2013 8:09 PM
AverageJoeOfToronto,
I appreciate your help, but the modified script gives me the same output the original script did. All services tested come back with a response of unknown..
Current State of the service "XYZ.MarketData.Staging" is Unknown
Current State of the service "XYZ.MarketData.Production" is Unknown
Current State of the service "Data.To.Production" is UnknownKeithdubya
-
Thursday, February 21, 2013 8:30 PM
Thomas Lee,
I continue to get the same output.
If I add a write-host $serviceinfo here.
foreach($Servicename in $Servicenames) { $Serviceinfo = Servicecheck -System $hostname -ServiceName $servicename Write-host $Serviceinfo DisplayInfo -ServiceName $Servicename -ServerInfo $ServiceInfo }All I get is a blank line, which is telling me that $Serviceinfo is not being assigned a value. This works fine as long as I am not using the foreach loop. Very strange.
Keithdubya
- Edited by Keithdubya Thursday, February 21, 2013 8:30 PM
-
Thursday, February 21, 2013 8:33 PMModerator
So add some 'write-host' statements inside the servicecheck function to see where your error is.Thomas Lee,
I continue to get the same output.
If I add a write-host $serviceinfo here.
foreach($Servicename in $Servicenames) { $Serviceinfo = Servicecheck -System $hostname -ServiceName $servicename Write-host $Serviceinfo DisplayInfo -ServiceName $Servicename -ServerInfo $ServiceInfo }All I get is a blank line, which is telling me that $Serviceinfo is not being assigned a value. This works fine as long as I am not using the foreach loop. Very strange.
Keithdubya
Thomas Lee <DoctorDNS@Gmail.Com>
-
Thursday, February 21, 2013 9:45 PM
Here is a POwerSHell way to do this that works.
Function ServiceCheck{ Param( $computername=$env:computername, $servicename='alg' ) $service=get-WmiObject win32_service -Computername $computername -filter "name = '$Servicename'" switch($service){ Running { Write-Host Current State of the service $Servicename is $Serviceinfo.state } Stopped { Write-Host Current State of the service $Servicename is $Serviceinfo.state -ForegroundColor red } default { Write-Host Current State of the service $Servicename is Unknown -ForegroundColor Yellow -BackgroundColor black } } } $Servicenames = Get-Content c:\myscripts\services.txt foreach($service in $Servicenames){ServiceCheck $Servicenames }¯\_(ツ)_/¯
-
Friday, February 22, 2013 1:26 PM
Thanks everyone for the suggestions. I really appreciate the assistance.
Keith
-
Saturday, February 23, 2013 2:39 AM
I finally figured out the problem with my script. The problem is that I had double quotes around the service entries in the services.txt file. They worked fine for the write-host statements in the Displayinfo function, but they did not work in the Servicecheck function. Thanks again everyone. I should have included my SERVICES.TXT. Thanks again for the advice.
Keithdubya
- Edited by Keithdubya Saturday, February 23, 2013 2:43 AM

