Ten monthes ago, when I started to work for DBI at a customer site, I had to work on groups managing the server accesses. The information can be queried via a simple web site:
- enter a server and it provides a list of groups
- enter a group and it provides the list of servers in it
I initially thought I will parse the returned HTML. Then, with my favorite browser and its powerful developer mode, I saw that result is actually XML.
I first made a Perl script. This was quickly developed, but it was not the most convenient for the Windows integration and for graphical capabilities on my customer laptop. So, with advice from my colleague, I moved to PowerShell.
This script is now 70kbytes which contains lots of tricks and ease that make me liked PowerShell very much. I will share one important aspect in this blog.
WebService
First thing, I needed was to actually read data from the URL with the right format. For this, Invoke-WebRequest Cmdlet looked to be perfect for the job.
The first issue encountered are the credentials, especially if it is possible for user to enter his credentials each time a call to the WebServervice is need. The parameter is “-UseDefaultCredentials”.
As laptop is integrated in a Windows domain and Web service uses SSO (Single Sign On), parameter will automatically pass currently logged user credentials transparently.
Lastly, “-Uri” is the most important parameter as it is the location of the service.
Command will finally look like:
$Response = Invoke-WebRequest -UseDefaultCredentials -Uri 'https://ServiceFQDN/server.cgi'
$Response variable is of type HtmlWebResponseObject which compose of the following members:
TypeName: Microsoft.PowerShell.Commands.HtmlWebResponseObject Name MemberType Definition ---- ---------- ---------- Dispose Method void Dispose(), void IDisposable.Dispose() Equals Method bool Equals(System.Object obj) GetHashCode Method int GetHashCode() GetType Method type GetType() ToString Method string ToString() AllElements Property Microsoft.PowerShell.Commands.WebCmdletElementCollection AllElements {get;} BaseResponse Property System.Net.WebResponse BaseResponse {get;set;} Content Property string Content {get;} Forms Property Microsoft.PowerShell.Commands.FormObjectCollection Forms {get;} Headers Property System.Collections.Generic.Dictionary[string,string] Headers {get;} Images Property Microsoft.PowerShell.Commands.WebCmdletElementCollection Images {get;} InputFields Property Microsoft.PowerShell.Commands.WebCmdletElementCollection InputFields {get;} Links Property Microsoft.PowerShell.Commands.WebCmdletElementCollection Links {get;} ParsedHtml Property mshtml.IHTMLDocument2 ParsedHtml {get;} RawContent Property string RawContent {get;set;} RawContentLength Property long RawContentLength {get;} RawContentStream Property System.IO.MemoryStream RawContentStream {get;} Scripts Property Microsoft.PowerShell.Commands.WebCmdletElementCollection Scripts {get;} StatusCode Property int StatusCode {get;} StatusDescription Property string StatusDescription {get;}
The two interesting fields are:
- StatusCode which will contain the http status. I expect to be equal to 200
- Content which is the actual result of the service. In our case, it will be xml text.
If WebService does not behave well, Invoke-WebRequest might raise a System.Net.WebException. To manage this, I used the typical Try/Catch block.
Final code block will look like:
Try { $Response = Invoke-WebRequest -UseDefaultCredentials -Uri 'https://ServiceFQDN/server.cgi' } Catch [System.Net.WebException] { $exception = $_.Exception Write-Host $exception.Exception.GetType().FullName + ': ' + $exception.Exception.Message }
It is possible to get the HTTP status code and manage this differently depending on it. To access the value:
$exception.Response.StatusCode
Going through content result
When request complete properly, I simply get the content and cast this to the xml type:
[xml][/xml] $xmlContent = $Response.Content
To go through the data, we can use ForEach loop:
ForEach ($element in $xmlContent.element) { Write-Host 'Working on $element' (... do the needed ...) }
On another WebService, it is even possible to choose result in xml of json. “-contentType” parameter can be used to specify result format.
Conclusion
While browsing customer intranet, I found some other WebService to manage user. As it is part of my day to day activity to add users to multiple groups, scripting that will also make me and my team gains lots of time.
On my next blogs on PowerShell, I will share what difficulties I found especially while moving from a simple script to a powerful tool with a graphical interface with many cool features:
- Create and automatically fill an email
- Create an Excel document and fill it
- …