• We’re currently investigating an issue related to the forum theme and styling that is impacting page layout and visual formatting. The problem has been identified, and we are actively working on a resolution. There is no impact to user data or functionality, this is strictly a front-end display issue. We’ll post an update once the fix has been deployed. Thanks for your patience while we get this sorted.

PowerShell: updating multiple variables in an array

oynaz

Platinum Member
Hi guys,

I am writing a PowerShell script which among other things will need to stop some services. These services can run on different server, and the script reads the server names from a config file.

My problem comes when I want to stop the services. I can stop a single service no problem (after having stolen most of the script from Scripting Guy), and could in theory just copy-paste my code x number of times while editing the appropriate variables, but I want to try my hand at using a foreach loop with an array.

If I just had to stop the services on a single server, I could just run the code below (Where I stop the services on the machine servername). However, the computername of each an every service varies, and is read from the config file.
How would I go about doing this? Any ideas?
I know I should make it a variable, and probably store the computernames from the config file in an array, but that is as far as I get.

Hope I made my problem clear enough!

Code:
function shutdownservices {

	#Shutdown services (script stolen from Scripting Guy - http://blogs.technet.com/b/heyscriptingguy/archive/2009/10/01/hey-scripting-guy-october-1-2009.aspx
	
	$logfilename = "c:\pstest\arraytest.txt"
	
	#Create array
	$aryServices = "hub", "biz"
	
	#Shutdown services
	foreach ($strService in $aryServices)
	{
	$strClass = "win32_service"
	$objWmiService = Get-Wmiobject -Class $strClass -computer servername # -----------------------------Here Is My Problem
	  -filter "name = '$strService'"
	if( $objWMIService.Acceptstop )
		 { 
		  $rtn = $objWMIService.stopService()
		  Switch ($rtn.returnvalue) 
			  { 
			   0 { $ErrorCodeBiz = "$strService stopped" }
			   2 { $ErrorCodeBiz = "$strService service reports access denied" }
			   5 { $ErrorCodeBiz = "$strService service cannot accept control at this time" }
			   10 { $ErrorCodeBiz = "$strService service is already stopped" }
			   DEFAULT { $ErrorCodeBiz = "$strService service reports ERROR $($rtn.returnValue)" }
			  }
		 }
	ELSE
		 { 
		  $ErrorCodeBiz = "$strService will not accept a stop request"
		 }
	
		#Write to logfile
	Add-Content $logfilename "Stopping $strService"
	Add-Content $logfilename "$ErrorCodeBiz"
	
	}
	

}

shutdownservices
 
I solved this myself. Yay.

The solution was to create a hash table to store the service/machine relationship, and refer GetWmiObject -computer to the hash.
 
Any reason you wouldn't use Get-Service, Stop-service, Start-service and the like? Then you can just spawn a session right on the server and retrieve the logs without all the WMI calls.
 
This is part of a complex script which will used to update a SharePoint based document-handling application. It is quite large, and installed at many customers. I want the script to be as universal as possible, so I do not have to modify it for each and every customer.

For this reason, I want the script to query the acceptStop property and notify the script, so the user can stop the services manualyl if needed.
AFAIK, Stop-Service cannot query acceptStop.
If I do not do this, I am afraid a service refusing to stop will make the script hang.

I got the idea from the (imo excellent) Hey! Scripting Guy! blog:

http://blogs.technet.com/b/heyscriptingguy/archive/2009/10/01/hey-scripting-guy-october-1-2009.aspx

It might be easier to use Stop-service (I am a PowerShell newbie).

(And yes, it might have been easier to code this in C# using PowerShell components instead of the other way round. Oh, well, that is for a future version.)
 
Back
Top