Listing 2 contains an excerpt from wmServerStatus.pl. As the code at callout B shows, this script uses the IWMSServer object (which $Server represents) to connect to the specified WMS server. The script then queries the server for the IWMSServer object's Status property value. The code at callout A defines the possible status values in a hash called %SERVER_STATUS.
The wmServerLimits.pl script demonstrates a more complicated interaction with a WMS server. This script retrieves the WMS server's limits. WMS defines multiple limits that prevent the service from exceeding a desired threshold. For example, the ConnectedPlayers limit defines how many players can be simultaneously connected to your service and the ConnectionRate limit defines the rate at which WMS allows new connections. These limits let WMS administrators determine how bandwidth and other resources are consumed.
You can download wmServerLimits.pl (as well as the other Perl scripts mentioned in this article) from the Windows Scripting Solutions Web site. (Go to http://www.windowsitpro.com/windowsscripting, enter 43757 in the InstantDoc ID text box, then click the 43757.zip hotlink.) To run wmServerLimits.pl, use the command
perl wmServerLimits.pl
[machine name]
[-p PUBPOINT]
This command is similar to the one for wmServerStatus.pl, except that it includes an optional -p switch. If you want to display the limits for a publishing point rather than the WMS server, you include -p PUBPOINT, where PUBPOINT is the name of that publishing point. (A publishing point is essentially a name with which content is associated. This concept is similar to how the name of a shared directory or a Microsoft IIS Web server maps virtual roots to directories on a hard disk.)
When wmServerLimits.pl runs, it uses the IWMSServer object to connect to the specified WMS server. The script then uses the IWMSServer object's Limits property to retrieve the IWMSServerLimits object, which stores information about the WMS server's limits. Next, the script checks to see whether the person launching the script wants the limits for a specific publishing point rather than for the WMS server. If the user includes the -p switch, the script connects to the specified publishing point. Finally, the script walks through each limit by name (in alphabetical order) and displays the name and value of each limit.
Managing WMS
Because the WMS platform is fully scriptable, creating Perl scripts to manage WMS is quite easy and useful. Let's take a look at how to create scripts that track how many clients are connected to WMS and track WMS errors.
Tracking connected clients. Administrators might need to know how many clients are connected to WMS for a variety of reasons. For example, they might have to shut down WMS or they might suspect that someone is trying to attack the service. The wmClients.pl script queries WMS publishing points to create a list of connected clients. Note that I said connected clients. There can be any number of downstream machines connected to WMS. The downstream machines might be players (i.e., computers of people using WMP to watch or listen to streaming-media content), distribution servers, or caching proxy servers. The script lets you specify the type of client to display: players or distribution servers. Caching proxy servers will be displayed as distribution servers. By default, the script displays players.
To understand how wmClients.pl works, you need to be familiar with its launch command, which has the syntax
perl wmClients.pl Machine
[-dlr] [-s SortField]
PubPoint [PubPoint2 [...] ]
This command has two mandatory arguments: Machine, which specifies the name of the target WMS server (unlike in the other scripts, this parameter isn't optional), and PubPoint, which specifies the name of the publishing point you want to query. You can specify more than one publishing point. If you specify "." (or don't specify a publishing point) for PubPoint, the script will query all the publishing points for the specified WMS server and display the result. If you want the script to list distributed servers instead of players, you need to include the -l switch. The -s, -d, and -r switches let you customize how values are sorted and displayed in the list. (For more information about these switches, see the syntax section in wmClients.pl.)
Like the other two scripts, wmClients.pl uses the IWMSServer object to connect to the specified WMS server. Then, wmClients.pl begins the process of walking through each publishing point to determine each client's status (i.e., disconnected, idle, open, or streaming). Listing 3, page 14, shows this part of the script. As callout A shows, the script first determines whether to query all publishing points or only specific publishing points. This determination is based on the action taken by the code that callout D shows. After the script processes all the command-line switches, the code at callout D determines whether publishing points were specified on the command line. The code performs this check by pushing all remaining passed parameters (which represent publishing-point names) into an array. Next, the code checks whether any of the parameters are a publishing-point name; if not, the code pushes "." onto the publishing-point array. Later the script walks through the list of publishing points in this array and runs the code at callout A for each one. The code at callout A assigns the $PubPoint variable to either the IWMSServer object ($Server) or the appropriate publishing point, depending on whether the publishing point name is "." or not, respectively. In either case, the script sets $PubPoint to a COM object that exposes one of two possible collection objects: Players (which represents a collection of players) and OutgoingDistributionConnections (which represents a collection of distribution servers). Which collection object the script uses depends on whether you include the -l switch on the command line.
Interestingly, the Players and OutgoingDistributionConnections collection objects are found both at the server's global level and at the publishing-point level. For this reason, the script works with minimal code.
The code at callout B queries the client objects' (i.e., connected players' or connected servers') status. This code calls the Win32::OLE extension's in() function to enumerate the items from the appropriate collection object. The in() function returns an array of COM objects, which the script sorts by using the Perl sort() function. The sort() function calls the script's SortPlayers() subroutine, which callout C shows, to provide the logic to sort the COM objects.
Tracking Errors. Administrators commonly query Windows machines for errors and warnings in the Win32 event log. This information helps determine whether there are problems or pending failures. Besides using the Win32 Event Log, WMS has a diagnostics interface called IWMSDiagnosticEvents that lets you see streaming mediarelated errors and warnings without having to crack open the Event Viewer.
All diagnostic events are stored in WMS. You can access them with the Microsoft Management Console (MMC) Windows Media Services snap-in or from your Web browser by using Windows Media Services Administrator for the Web. You can also access diagnostic events through scripts. You'll find one such script, wmServerErrors.pl, on the Windows Scripting Solutions Web site.
The wmServerErrors.pl script connects to WMS on the specified machine, then uses the Win32::OLE extension's in() function to enumerate each IWMSDiagnosticEvent object in the IWMSDiagnosticEvents collection object. The script sorts the enumerated objects in chronological order, according to the IWMSDiagnosticEvent object's Time property. Thus, the script processes the diagnostic events in the order in which they were generated.
The script copies the property value of each IWMSDiagnosticEvent object into a hash called %ErrorData, then writes the data to the screen. The property values are first copied to a local hash for two reasons: First, the write command prints global or local variables only. The write command won't print a variable's data if you lexically scope the variable by using the my keyword. Second, write format specifies that one of the IWMSDiagnosticEvent object property values must be modified to accommodate wrapping to the next line when displayed. However, all the property values are read-only. Copying the values into the read-write %ErrorData hash allows the modification of those property values.
Note that %ErrorData is a local hash. In wmServerErrors.pl, the line
local %ErrorData = %$Error;
not only declares that %ErrorData has a local scope but also assigns all the hash keys and values from the $Error hash reference. Because $Error is a reference to a hash, the script dereferences the hash reference by placing the % sign in front of the $Error scalar variable.
You can run wmServerErrors.pl by simply passing in the name of the WMS server and optionally passing in the -r switch, which will remove all errors from the server. Follow the command syntax
perl wmServerErrors.pl
[machine name] [-r]
Create Your Own WMS Scripts
This brief introduction to WMS demonstrates how simple it can be to write scripts that retrieve WMS information and manage the service. Using the WMS 9 Series object model, you can also write sophisticated streaming-media scripts that simplify building and maintaining WMS sites.