How to Talk to MDT WebService Using PowerShell
Hi All,
As I am not that at ease with writing custom scripts for Microsoft Deployment Toolkit in WSF or VBS, but I am using PowerShell a lot, so I decided to try and use PowerShell (got to love it ;-) to connect to - and get a responce from the MDT WebService (http://mdtcustomizations.codeplex.com/).
For those of you who don't know this excelent set of tools, you should at least visit the website and read about it. In short, this is a set of scripts, accassible from a webpage, whith which you can do a lot of things not available through native MDT.
In my organization, we use this service to store and look up the "netbootGUID" property of an AD computer object, as well as move a computeraccount (if it exists) to a staging OU prior to redeployment - and back to the original OU after deployment is done.
Preperations
To prepare for this to work, you do need a few things.
First, you need to install IIS. Remember to include ASP.NET. This is not mentioned in the installation documentation of the Webservice.
Second, download and extract the webservice ZIP file and install it as an application, as described in the installation documentation.
Optional but wise: create a new AD useraccount with the rights to write to and read properties of AD objects and assign that useraccount to the Webservice Application Pool in IIS. All calls to the webservice will be run using this users credentials.
Verfy that the webservice is oparational by opening your browser and accessing http://webserver/mdtws/ad.asmx, where webserver is the server running IIS and mdtws the virual directory of the webservice application.
And now for the code
Access to the webservice is really a matter of a single line of code:
New-WebServiceProxy -Uri "http://webserver/mdtws/ad.asmx?WSDL"
But that only creates a connection to the webservice. So how do we interact with it?
Well, if a variable is assigned to the New-Webserivce call, that var can then be use to access the various webservice scripts.
$wsCall = New-WebServiceProxy -Uri "http://webserver/mdtws/ad.asmx?WSDL" -ErrorAction SilentlyContinue
Now we can see what this object holds, by asking PowerShell to display its properties.
$wsCall | Get-Member
After running this command, you can see that a list of Methods and Properties is returned. Don't they look familiar? Yes you are right: these are the scripts that are available through the webservice. Now to use one of the scripts - say DoesComputerExist, you can do something like this:
$wsCall.DoesComputerExist(computername)
The DoesComputerExist script takes only one parameter, the name of the computer. Its responce is ether "true" or "false". Now for a more practicle example, we can use WMI to get the current computername and ask the webserivce if it exists, like this:
#use WMI to get the current computername
$csProp = Get-WmiObject -Class Win32_ComputerSystem -ErrorAction SilentlyContinue
$myName = $csProp.Name
#use the MDT webservice to see if the computer exists
$wsCall = New-WebServiceProxy -Uri "http://webserver/mdtws/ad.asmx?WSDL" -ErrorAction SilentlyContinue
$isComputer = $wsCall.DoesComputerExist($myName)
#display the results
if($isComputer) {
Write-Host "Computeraccount $myName was found in AD"
} else {
Write-Host "Computeraccount $myName does not exist"
}
I'll give one final example.
If a webservice script requires more than one parameter, you can specify them as a comma separated list.
If you want to set the netbootGUID value in the AD computeraccount, for example, you must use a script called SetComputerNetbootGuid. That script takes two parameters: ComputerName and netbootGUID.
Here's the complete script to write a computers UUID in the AD property netbootGUID:
#use WMI to get the current computername
$csProp = Get-WmiObject -Class Win32_ComputerSystem -ErrorAction SilentlyContinue
$myName = $csProp.Name
#use WMI to get the current computer's uuid
$cpProp = Get-WmiObject -Class Win32_ComputerSystemProduct -ErrorAction SilentlyContinue
$myUUID = $cpProp.UUID
#use the MDT webservice to set the computers netbootGUID
$wsCall = New-WebServiceProxy -Uri "http://webserver/mdtws/ad.asmx?WSDL" -ErrorAction SilentlyContinue
$wsResp = $wsCall.SetComputerNetbootGuid($myName,$myUUID)
#display the results
if($wsResp) {
Write-EventLog -LogName System -EntryType Information -EventID 10001 -Source eventlog -Message "SetNetbootGuid: UUID correctly set for $myName."
Write-Host "UUID correctly set for $myName"
} else {
Write-EventLog -LogName System -EntryType Error -EventID 10001 -Source eventlog -Message "SetNetbootGuid: Failed to set UUID for $myName."
Write-Host "FAILED to set UUID for $myName"
}
I think you get the drift. You're on your own now ;-)
Good luck,
Martin