Some time ago I was asked if it was possible to import a list of resources rather than having to enter them manually in the GroupWise Administration console. I believe that the organisation who was requesting this had acquired several hundred laptops that they wished to make available to their users for scheduling. Unsurprisingly, they were not keen on having a user input each laptop as a resource, and having all the possible errors that could involve, not to mention the time that it would take.
Having played around with the GroupWise REST APIs a little when I was creating the million user GroupWise system (see OHM Issue 28, 2015/1, p5-7) I was sure that I could achieve what they required. So building on the articles that Tommy Mikkelsen wrote on the subject (in OHM23, OHM24, OHM26) I decided to give it a shot.
What I wanted to do first was find out what the field names were for the fields associated with a resource. To do that I just used a bowser to access an existing resource, to see the fields. I manually created a resource with the fields populated that I wanted on a post office then I used a browser to visit
https://<server>:9710/gwadmin-service/domains/<domain name>/postoffices/<postoffice>/resources
Just replace <server>, <domain> and <postoffice> as appropriate. You will be prompted for authentication credentials. Just enter the admin credentials, or someone with admin rights to the post office. This will return a list of the resources on that post office and the fields that each has populated as shown below.
<object xsi:type=”resource” url=”/gwadmin-service/domains/pridom/postoffices/pripost/resources/Laptop%201”>
<guid>4DB45F80-0109-0000-8570-726965326434</guid>
<id>RESOURCE.pridom.pripost.Laptop 1</id>
<lastModifiedBy>admin.utopiagw</lastModifiedBy>
<lastModifiedOp>MODIFY</lastModifiedOp>
<name>Laptop 1</name>
<timeCreated>1485934747000</timeCreated>
<timeLastMod>1485935013000</timeLastMod>
<description>Laptop 1</description>
<domainName>pridom</domainName>
<postOfficeName>pripost</postOfficeName>
<preferredEmailAddress>Laptop1@utopia.microfocus.com</preferredEmailAddress>
<visibility>SYSTEM</visibility>
<fileId>bf5</fileId>
<owner>amarsden</owner>
<resourceType>RESOURCE</resourceType>
</object>
So now we have the field names we want to use.
- name
- domainName
- postOfficeName
- owner
This is the really the minimum that we need for the task. We could include resourceType, but need not. as the default is RESOURCE, the other options being PLACE and ROLE. We could also use some of the additional fields, for instance to set the visibility, description or even the fileId should we wish. However let’s keep it simple.
A sample csv file for the import is:
domain,postoffice,name,owner
pridom,pripost,Laptop 1,rredgrave
pridom,pripost,Laptop 2,rredgrave
pridom,pripost,Laptop 3,rredgrave
pridom,pripost,Laptop 4,rredgrave
You can write the code in whatever environment best suits you. I decided to write it in PowerShell as that is something that is freely available to all, not to mention than many of Tommy’s original examples were written as PowerShell scripts. The code I came up with is shown below.
#*** Lets start setting up some static variables : ***
#*** $mybaseUri is the address of the admin service ***
#*** $myAdmin and $myPwd are the the credentials of a
user with administrative rights ***
$mybaseUri = “https://172.17.2.86:9710/gwadmin-service”
$myAdmin = “admin”
$myPwd = “n0v3ll”
#*** End of static variables ***
#*** We need to Ignore self minted certificates ***
add-type @”
using System.Net;
using System.Security.Cryptography.
X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
“@
[System.Net.ServicePointManager]::CertificatePolcy
= New-Object TrustAllCertsPolicy
#*** End Ignore self minted certificates ***
#*** Put the authenication Credentials in the correct
format. This should be Base64 encoded and UTF8 ***
$encoded = [System.Convert]::ToBase64String(
[System.Text.Encoding]::
UTF8.GetBytes($myAdmin + “:” + $myPwd ))
$headers = @{Authorization = “Basic “ + $encoded}
#*** Set the file name to import ***
$list = Import-Csv “resources.csv”
#*** Loop through each line in the input csv file ***
foreach($entry in $list) {
#*** Print out which item we are importing ***
echo “importing : $entry”
#*** Set up the parameters for creating the resource ***
#*** Domain and post office can be removed if they are
going to be hard coded ***
$myGWRes = @{
name=$entry.name;
owner=$entry.owner;
domain=$entry.domain;
postOfficeName=$entry.postoffice
}| ConvertTo-Json
$myGWRes = [System.Text.Encoding]::UTF8.
GetBytes($myGWRes)
#** set up the uri ***
#** The domain and post office could be hard coded
and excluded from the input file if all resuources ***
#** are on the same post office ***
$myUri = $myBaseUri +
“/domains/” + $entry.domain +
“/postoffices/” + $entry.postoffice +
“/resources”
#*** Send the request ***
#*** note I have spread this out over multiple lines ***
#*** with a backtic ` or grave accent ***
$req = Invoke-WebRequest `
-Uri $myUri `
-Headers $headers `
-ContentType application/JSON `
-Body $myGWRes `
-Method POST
#*** You could do something with the response ***
#***$req if you want, but I won’t. ***
}
This article was first published in OH Magazine Issue 36, 2017/1, p26-27
The Script does not work. There comes an error message a braket “}” failed.
Who can resolve the problem. Thanks.
Hi Thomas, I’ll check out the script. The error may have crept in when I transferred the original to the online version. John
There was indeed a missing } right at the end of the script. I’ve now updated the posting and hope it works correctly now for you. Thanks for getting in touch.