2018-02-09 03:03 PM
If you used web services to run a report that only listed users in a Record permission field, how would you limit the results to only returning the user id of the users in the report.
powershell
$api_url = $base_url + "/ws/search.asmx"
$ws = New-WebServiceProxy -Uri $api_url -Class Search -Namespace webservice
$report_id = 12012
$page = 1
Do {
"Page " + $page
[xml] $xdoc = $ws.SearchRecordsByReport($session_token, $report_id, $page)
$xdoc.InnerXml
$page++
}
While ($xdoc.Records.Record.Count -gt 0)
The results are basically laid out simply enough but I can't seem to figure out how to access the Users level to grab the @id when the report returns more than one name. There are roughly 11 users in the list but it basically looks like this, with 11 entries of <users>.
When the report returns only 1 name, it is easy to do but the web services call seems to change when there are multiple users and does not allow me to get to the <User> level, or at least I haven't found a way.
<?xml version="1.0" encoding="utf-16"?>
<Records count="6">
<Metadata>
<FieldDefinitions>
<FieldDefinition id="21548" guid="bd906ce7-296a-4f7f-b9dc-367f46aa51f8" name="Information Owner(s)" alias="Information_Owners" />
<FieldDefinition id="18049" guid="61ae6903-9017-43df-bdb0-f72b1a9971ea" name="System Name" alias="Authorization_Package_Name" />
</FieldDefinitions>
</Metadata>
<LevelCounts>
<LevelCount id="270" guid="086d9857-bfdf-4541-8464-10d2e0e588d9" count="6" />
</LevelCounts>
<Record contentId="273528" levelId="270" levelGuid="086d9857-bfdf-4541-8464-10d2e0e588d9" moduleId="472" parentId="0">
<Field id="21548" guid="bd906ce7-296a-4f7f-b9dc-367f46aa51f8" type="8">
<Users>
<User id="202" firstName="General User Info Owner HHSC" lastName="Test User">tuser6</User>
</Users>
<Groups />
</Field>
</Record>
</Records>
The call to web services also adds the key field to the results despite not being in the report. Is that standard?
Thanks. I am attempting to have a report return users to be added to a group by web services.
2018-02-09 07:19 PM
Yes, the key field will be returned in the results by SearchRecordsByReport and ExecuteSearch. The <Groups /> line is an empty XML Element which means no groups.
Here is a snippet on how to loop thru the records and pull the users from a specific field.
Do {
"Page " + $page + "`r`n"
[xml] $xdoc = $ws.SearchRecordsByReport($session_token, $report_id, $page)
$recs = $xdoc.SelectNodes("/Records/Record")
foreach($rec in $recs)
{
"Content Id: " + $rec.contentId
$field = $rec.SelectSingleNode("Field[@id='21548']")
foreach($user in $field.SelectNodes("Users/User"))
{
$tmp_userid = $user.GetAttribute("id")
$tmp_username = $user.InnerText
$tmp_fullname = $user.GetAttribute("firstName") + " " + $user.GetAttribute("lastName")
"User Id: " + $tmp_userid + " Username: " + $tmp_username + " Name: " + $tmp_fullname
}
"`r"
}
#$xdoc.InnerXml
"`r"
$page++
} While ($xdoc.Records.Record.Count -gt 0)
Sample output:
2018-02-09 07:19 PM
Yes, the key field will be returned in the results by SearchRecordsByReport and ExecuteSearch. The <Groups /> line is an empty XML Element which means no groups.
Here is a snippet on how to loop thru the records and pull the users from a specific field.
Do {
"Page " + $page + "`r`n"
[xml] $xdoc = $ws.SearchRecordsByReport($session_token, $report_id, $page)
$recs = $xdoc.SelectNodes("/Records/Record")
foreach($rec in $recs)
{
"Content Id: " + $rec.contentId
$field = $rec.SelectSingleNode("Field[@id='21548']")
foreach($user in $field.SelectNodes("Users/User"))
{
$tmp_userid = $user.GetAttribute("id")
$tmp_username = $user.InnerText
$tmp_fullname = $user.GetAttribute("firstName") + " " + $user.GetAttribute("lastName")
"User Id: " + $tmp_userid + " Username: " + $tmp_username + " Name: " + $tmp_fullname
}
"`r"
}
#$xdoc.InnerXml
"`r"
$page++
} While ($xdoc.Records.Record.Count -gt 0)
Sample output:
2018-02-13 06:19 PM
Thank you Jeff.
In an effort to share, this is my rough draft of my first attempt at a script to use ws (with some help from a colleague). Happy to take thoughts. I am now going to go through it and writing more text for informational purposes and maybe look for some efficiencies.
Intent: Read a list of users from a report. Assign them to a group. Remove any users in the group not listed in the report.
Powershell
$base_url = "http://server/Archer"
$instance = "Archer"
$user_domain = ""
$username = "apiuser"
$password = "password"
$groupid = "229"try
{
$api_url_general = $base_url + "/ws/general.asmx"
if ($user_domain -eq "") {
$ws = New-WebServiceProxy -Uri $api_url_general -Class General -Namespace webservice -ErrorAction Stop
$session_token = $ws.CreateUserSessionFromInstance($username, $instance, $password)
}
else {
$ws = New-WebServiceProxy -Uri $api_url_general -Class General -Namespace webservice -ErrorAction Stop
$session_token = $ws.CreateDomainUserSessionFromInstance($username, $instance, $password, $user_domain)
}
$session_token
}
catch {
$session_token = $null
$_.Exception|Format-List -Force
exit
}#run report, return user id in a list
[System.Collections.ArrayList] $UserList = @()
$api_url_search = $base_url + "/ws/search.asmx"
$ws = New-WebServiceProxy -Uri $api_url_search -Class Search -Namespace webservice
$report_id = 12012
$page = 1do
{
[xml] $xdoc = $ws.SearchRecordsByReport($session_token, $report_id, $page)
Foreach($User in $xdoc.Records.Record.Field.Users.User)
{ if ($userlist.indexof($user.id) -eq -1) { $UserList.Add($User.id) | out-null} }
$page++
}
while ($xdoc.Records.record.count -gt 0)#add to group
$api_url_ac = $base_url + "/ws/accesscontrol.asmx"
$ws = New-WebServiceProxy -Uri $api_url_ac -Class AccessControl -Namespace webservice("Adding users to group: " + $ws.getgroup($session_token,$groupid))
ForEach ($id in $userlist) {
$ws.AddUsersToGroup($session_token, $id, $groupid)
#$id
}#get group information, return user id
$ws = New-WebServiceProxy -Uri $api_url_ac -Class AccessControl -Namespace webservice
[xml] $GroupInfo = $ws.GetGroupInformation($session_token, $groupid)
$GroupUserId = $GroupInfo.Group.Members.Users.User.Id#remove user from group by user id
$ws = New-WebServiceProxy -Uri $api_url_ac -Class AccessControl -Namespace webservice
Foreach ($IdListed in $GroupUserId) {
If ($Userlist -notcontains $IdListed) {
$ws.RemoveUserFromGroup($session_token, $IdListed, $groupid)
}
}