Executing Web services – a generic MDT script
As a frequent reader of this blog you have probably seen already a couple posts where we had to execute a web service to accomplish a certain task or get a specific value, etc. MDT itself takes away a lot of the hassle you have to deal with normally, if working with web services. In their easiest way, you simply define the complete web service call in the customsettings.ini and let the Gather step do it’s magic.
But sometimes this isn’t enough as we need to call these web services at a later point in time, so we can’t use the gather step for these calls. In a couple examples I wrote some simple scripts that executed a specific web service method and in some cases evaluates the result. And if you have a look on those scripts, they all looked quite identical as most of the stuff necessary to call the web service is pretty similar.
So I thought it might be a good idea to have a generic script with the ability to pass in a couple parameters to influence the behaviour and by doing so, having one way to call (almost) any web service. The script I’m providing here is just limited in the way that it can only process a maximum of one result or no result at all. However this actually covers most of the cases we need it for (Setting computer description in AD, Getting Resource ID from SCCM, Adding computer to AD group, remove it from SCCM collection, etc.). There might be some more extensive evaluation similar to the gather step in a future version but for now, being able to cover the most common scenarios should be enough to be published.
The configuration of the webservice like the path, parameters, etc. will still be defined in the settings file. On default it will use the customsettings.ini, but you can supply a parameter to overwrite this and point it to a different settings file. The only required parameter for the script is the section that contains the web service definition. This parameter is called “wsSection”. Actually all parameters have a suffix of “ws” to ensure that they don’t overlap with any existing or future MDT property.
In the settings file we might have the following section:
[MoveComputerToOU] WebService=http://YourWebServer/YourWSFolder/AD.asmx/MoveComputerToOU Parameters=OSDComputerName,MachineObjectOU OSDComputerName=ComputerName MachineObjectOU=OUPath
This web service function will be able to move the specified computer to the specified OU (See Moving computer in Active Directory using a webservice or Moving computer in Active Directory – Step by Step for more detailed information on this). We assume that the MDT property OSDComputerName has been filled with the correct computername and also that MachineObjectOU contains the path to the OU the computer shall be moved to. That’s typically done by the Gather step at the beginning of the Task Sequence. All we now need to do to execute this function is adding a “Run command line” step with the following command:
cscript.exe %ScriptRoot%ZTI_ExecuteWebservice.wsf /wsSection:MoveComputerToOU
Assuming no error happens the computer will now be moved to the new OU. For sure as the other MDT scripts as well, this script will write an extensive log file (ZTI_ExecuteWebservice.log).
OK. This was an easy (but actually often used) one. Now, how do we handle Results? Lets have a look at the following section:
Now to execute this webservice we can add again a new “Run Command Line” step that runs the following command
cscript.exe %ScriptRoot%ZTI_ExecuteWebservice.wsf /wsSection:GetADSite /wsProperty:ADSite /wsResultName:string
This would now call the function and write the value contained in the “string” element into the property “ADSite”. Actually in this case it would even be possible to omit the “wsResultName” as it will default to “string” if nothing is supplied. But I would recommend to always supply this parameter. Now if you have used web services already you might ask, why I don’t use the built-in function to evaluate the result. This section
[GetADSite] WebService=http://YourWebServer/YourWSFolder/AD.asmx/GetADSite ADSite=string
would actually do the same trick. And you are totally right. It really depends on your needs as both are working quite similar. There are two main differences.
- The script will create the property no matter if it has been defined before. In MDT you would need to either use a default property, add a custom one to the ZTIGather.xml file or define it in the properties part of the customsettings.ini
- The script will overwrite the value if anything has been stored before. This is actually the opposite behavior of MDT that on default stores values only (well almost only) if no value has been set before. This can only be tweaked by making changes to the ZTIGather.xml file. It’s still possible to establish the same behavior as in MDT by using the “wsOverwrite” parameter. So calling the following
cscript.exe %ScriptRoot%ZTI_ExecuteWebservice.wsf /wsSection:GetADSite /wsProperty:ADSite /wsResultName:string /wsOverwrite:False
would do the same evaluation as MDT. So whatever fits best, you can use it 😉
The script will take a couple more parameters. I will just list them for completeness:
- wsIniFile – Used to supply the name of the settings file with the web service definitions. Will use customsettings.ini on default
- wsStoreResult – If set to Yes (or True) it will store the raw Result of the web service call into the property “wsResult” so that it can be used by your custom scripts afterwards
- wsSelectionNamespace – Define the selection namespace of the web service function. If you are using the Deployment Web service it’s not necessary to make any change. If you are using other web services you might need to make use of this parameter. See Making custom database and web service scripts work again in MDT 2010 for more details.
For a complete list of parameters just call
The script has been written to work with MDT 2010/MDT 2010 Update 1. If you want to use it in plain SCCM OSD deployments, just add this script and the ZTIDataAccess.vbs and ZTIUtility.vbs files from a MDT 2010 installation into a package. That should be enough to get it working without any MDT integration. But I still highly recommend the MDT integration.
I appreciate all comments and suggestions.