Sample MDT Web Service

I’m here at the Mall of America in Minneapolis Minnesota at the Minnesota Management Summit 2014 (MMS for short). #mmsminnesota

Johan Arwidmark and I are giving a talk today about MDT Web Services.

Web services are another way we can get variables into our MDT Task Sequence environment from the Gather step (ZTIGather.wsf). The other ways we can get variables into our system are the Wizard, Customsettings.ini, Bootstrap.ini, a SQL Database, and more!

Kodiak

Back when I worked at Microsoft, we had a project to deploy the System Center Suite to a specified group of machines using a custom Task Sequence. Boy, was this Task sequence HUGE, with multiple branches, and different parts run on different machines. We wanted a way to control and monitor this task sequence from a remote management console (a laptop).

The design we came up with was to use a MDT Service to feed variables to each process, and to show progress.

The Developers stared asking about the specifics of how the protocol worked, so I wrote a demo program in C# to illustrate how this worked. Honestly the sample script wasn’t that hard, it was about half the size of this Blog Post. :^).

The Code

First up we create a new .NET class called MDTDataContext that contains two methods, one for getting events from MDT, and the other for sending variables back to the Client.

  [ServiceContract]
  public class MDTDataContext
  {

    [OperationContract]
    [WebGet]
    public String PostEvent(String uniqueId, String computerName, String messageId, 
      String severity, String stepName, short currentStep,
      short totalSteps, String id, String message, String dartIP, 
      String dartPort, String dartTicket, String vmHost, String vmName)
    {
      Console.WriteLine(
        String.Format("MDT: Event {0} step {1} of {2} severity {3} from {4}: \"{5}\": {6}", 
          messageId, currentStep, totalSteps, severity, computerName, stepName, message));
      return uniqueId;
    }

    [OperationContract]
    [WebGet(UriTemplate = "GetSettings?uniqueId={uniqueId}")]
     public Stream GetSettings(String uniqueId)
     {
        WebOperationContext.Current.OutgoingResponse.ContentType = "text/xml";

        XmlDocument result = new XmlDocument();
        result.LoadXml("<Settings><ComputerName>foo_" + uniqueId + 
          "</ComputerName><TaskSequenceID>TASKID_" + uniqueId + 
          "</TaskSequenceID></Settings>");
        return new MemoryStream(Encoding.UTF8.GetBytes(result.OuterXml));
    }
  }

In this case the variables returned by the Web Service is pretty light, it’s only a XML blog returning the ComputerName and TaskSequenceID derived from the client input. The client input is a variable called T LTIGUID.

Then we create a main() function to handle the processing

  static void Main(string[] args)
  {
    Uri[] uri = new Uri[] { new Uri("http://localhost:3994/MDTMonitorEvent") };
    WebServiceHost dsHost = new WebServiceHost(typeof(MDTDataContext), uri);
    dsHost.Open();
    Console.WriteLine("Host is running; press a key to stop");
    Console.ReadKey();
    dsHost.Close();
  }

It’s pretty simple, we are just creating a new instance of our MDT Web Service, and waiting until the user says to stop.

In addition there is also a sample MDT Customsettings.ini file in the zip file to get you started:

[Settings]
priority=default

[default]
EventService=http://localhost:3994

Easy

Testing

Let’s run the sample and see what happens.

Extract out the code from the *.zip file and open in an Elevated instance of Visual Studio 2013 (express is OK). Press F5 and run.

Now, let’s open an elevated command prompt and test it out.

First don’t forget to remove any local c:\minint directory. If you have any left over variables in the environment, ZTIGather.wsf may not import the correct variables.

Then, run the ZTIGather.wsf script.
/NoLocalOnly parameter to prevent hardware discovery step.
/INIFile:[file] parameter to specify our
/LTIGuid:[value] is our parameter to the service

C:\>rd /s /q c:\minint 
C:\>cscript //NoLogo c:\DeploymentShare\Scripts\ZTIGather.wsf /nolocalonly /inifile:c:\SampleMDTDataService\SampleMDTDataService\test.ini /LTIGUID:HelloWorld

Property LogPath is now = C:\MININT\SMSOSD\OSDLOGS
Property nolocalonly is now =
Property inifile is now = c:\SampleMDTDataService\SampleMDTDataService\test.ini
Property LTIGUID is now = HelloWorld
Microsoft Deployment Toolkit version: 6.2.5019.0
Property Debug is now = FALSE
------------------------- Object Initialization -------------------------
------------------------- Initialization -------------------------
Synchronizing the environments.
Finished synchronizing the environments.
Skipping local settings gathering because it has already been done.
Processing the  phase.
Determining the INI file to use.
Using COMMAND LINE ARG: Ini file = c:\SampleMDTDataService\SampleMDTDataService\test.ini
Finished determining the INI file to use.
Using from [Settings]: Rule Priority = DEFAULT
------ Processing the [DEFAULT] section ------
Property EVENTSERVICE is now = http://localhost:3994
Using from [DEFAULT]: EVENTSERVICE = http://localhost:3994
------ Done processing c:\SampleMDTDataService\SampleMDTDataService\test.ini ------
Property COMPUTERNAME is now = foo_HelloWorld
Obtained COMPUTERNAME value from web service:  COMPUTERNAME = foo_HelloWorld
Property TASKSEQUENCEID is now = TASKID_HelloWorld
Obtained TASKSEQUENCEID value from web service:  TASKSEQUENCEID = TASKID_HelloWorld
Remapping variables.
Property TaskSequenceID is now = TASKID_HELLOWORLD
Property DeploymentType is now =
Finished remapping variables.
ZTIGather processing completed successfully.
Property OSDComputerName is now = foo_HelloWorld
Event 41001 sent: ZTIGather processing completed successfully.

Additionally, We can also send messages back to the console with the following code in VBScript:

<job id="ZTISetVariable">
        <script language="VBScript" src="c:\deploymentshare\scripts\ZTIUtility.vbs"/>
        <script language="VBScript" src="c:\DeploymentShare\Scripts\ZTIDataAccess.vbs"/>
        <script language="VBScript">

ologging.CreateEvent 12345, LogTypeInfo, "This is a Major MMS Event", Array(1,2,"cat","Dog")

        </script>
</job>

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s