Last active
November 17, 2018 22:11
-
-
Save darrenjrobinson/eb41e9b3e246cb327ed5e981bfb53e4f to your computer and use it in GitHub Desktop.
xMatters PowerShell FIM/MIM Management Agent - Export Script. Supporting blog post is located here https://blog.darrenjrobinson.com/building-a-fimmim-management-agent-for-xmatters/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
PARAM ( | |
$Username, | |
$Password, | |
$Credentials, | |
$OperationType | |
) | |
BEGIN | |
{ | |
# Debug Logging | |
$DebugFilePath = "C:\PROGRA~1\MICROS~4\2010\SYNCHR~1\EXTENS~2\xMatters\Debug\xMatters.txt" | |
if(!(Test-Path $DebugFilePath)) | |
{ | |
$DebugFile = New-Item -Path $DebugFilePath -ItemType File | |
} | |
else | |
{ | |
$DebugFile = Get-Item -Path $DebugFilePath | |
} | |
# API Timeout (seconds) | |
[int]$Global:apiTimeout = 20 | |
# xMatters is using TLS 1.2 | |
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 | |
function DeviceExists ($n, $d) { | |
$Global:return = $null | |
try{ | |
$Global:return = Invoke-RestMethod -Uri ($xMattersBaseURI + $createDeviceURI +"/$($n)|$($d)") -Headers @{Authorization = "Basic $($Site_EncodedAuth)"} -method GET -ContentType 'application/json;charset=UTF-8' -TimeoutSec $Global:apiTimeout -ErrorAction SilentlyContinue | |
if ($Global:return){"Device Exists: $($n)|$($d)" | Out-File $DebugFile -Append} | |
} catch { | |
$Global:return = $null | |
switch ($_.Exception.Response.StatusCode.value__){ | |
"400" {"Device Check: 400 Bad Request" | Out-File $DebugFile -Append} | |
"404" {"Device Check: 404 Not Found" | Out-File $DebugFile -Append} | |
Default {"Device Check: $($_.Exception.Response.StatusDescription)" | Out-File $DebugFile -Append} | |
} | |
} | |
} | |
function UpdateDevice ($b) { | |
$return = $null | |
try{ | |
$Global:return = Invoke-RestMethod -Uri ($xMattersBaseURI + $createDeviceURI) -Headers @{Authorization = "Basic $($Site_EncodedAuth)"} -method POST -ContentType 'application/json;charset=UTF-8' -body ($b | convertto-json) -TimeoutSec $Global:apiTimeout -ErrorAction SilentlyContinue | |
if ($Global:return){"Successfully Updated Device " +($b | convertto-json) | Out-File $DebugFile -Append } | |
} catch { | |
$Global:return = $null | |
"Failed updating Device " +($b | convertto-json) | Out-File $DebugFile -Append | |
switch ($_.Exception.Response.StatusCode.value__){ | |
"400" {"Update Device: Bad Request" | Out-File $DebugFile -Append} | |
"404" {"Update Device: Device Not Found" | Out-File $DebugFile -Append} | |
Default {$_.Exception.Response.StatusDescription | Out-File $DebugFile -Append } | |
} | |
} | |
} | |
function DeleteDeviceByID ($i) { | |
$return = $null | |
try{ | |
$Global:return = Invoke-RestMethod -Uri ($xMattersBaseURI + $createDeviceURI +"/$($i)") -Headers @{Authorization = "Basic $($Site_EncodedAuth)"} -method Delete -ContentType 'application/json;charset=UTF-8' -TimeoutSec $Global:apiTimeout -ErrorAction SilentlyContinue | |
if ($Global:return){"Successfully deleted Device: $($i)" | Out-File $DebugFile -Append } | |
} catch { | |
$Global:return = $null | |
"Failed deleting device: $($i)" | Out-File $DebugFile -Append | |
switch ($_.Exception.Response.StatusCode.value__){ | |
"400" {"Delete Device: Bad Request" | Out-File $DebugFile -Append} | |
"404" {"Delete Device: Device Not Found" | Out-File $DebugFile -Append} | |
Default {$_.Exception.Response.StatusDescription | Out-File $DebugFile -Append } | |
} | |
} | |
} | |
function UpdateUser ($b) { | |
$return = $null | |
try{ | |
$Global:return = Invoke-RestMethod -Uri ($xMattersBaseURI + $xMattersCreateUsersURI) -Headers @{Authorization = "Basic $($Site_EncodedAuth)"} -method POST -ContentType 'application/json;charset=UTF-8' -body ($b | convertto-json) -TimeoutSec $Global:apiTimeout -ErrorAction SilentlyContinue | |
if ($Global:return){"Successfully updated User: " + ($b | convertto-json) | Out-File $DebugFile -Append } | |
} catch { | |
$Global:return = $null | |
"Update User failed " + ($b | convertto-json) | Out-File $DebugFile -Append | |
switch ($_.Exception.Response.StatusCode.value__){ | |
"400" {"Update User: Bad Request" | Out-File $DebugFile -Append} | |
"404" {"Update User: Device Not Found" | Out-File $DebugFile -Append} | |
Default {$_.Exception.Response.StatusDescription | Out-File $DebugFile -Append } | |
} | |
} | |
} | |
function returnSuccess () { | |
#Return the result to the MA | |
$Global:obj = @{} | |
$Global:obj.Add("[Identifier]",$Identifier) | |
$Global:obj.Add("[ErrorName]","success") | |
$Global:obj | |
} | |
function returnError () { | |
$ErrorName = "Script Error" | |
$errordetail = $error[0].exception | |
#Return the result to the MA | |
$Global:obj = @{} | |
$Global:obj.Add("[Identifier]",$Identifier) | |
$Global:obj.Add("[ErrorName]",$ErrorName) | |
if($ErrorDetail){$obj.Add("[ErrorDetail]",$ErrorDetail)} | |
$Global:obj | |
} | |
"Starting Export : " + (Get-Date) | Out-File $DebugFile -Append | |
"ExportType : $ExportType " | Out-File $DebugFile -Append | |
# Lithnet MIIS Automation Module | |
# Required to get full CS and MVObjects | |
Import-Module LithnetMIISAutomation | |
# xMatters Auth | |
$site_auth = "$($Username):$($Password)" | |
# xMatters URI's | |
$xMattersBaseURI = 'https://customer.hosted.xmatters.com' | |
# Create and Modify | |
$xMattersCreateUsersURI = '/api/xm/1/people' | |
# Create User Device | |
$createDeviceURI = "/api/xm/1/devices" | |
$site_Bytes = [System.Text.Encoding]::utf8.GetBytes($site_auth) | |
$Site_EncodedAuth=[Convert]::ToBase64String($site_Bytes) | |
} | |
PROCESS | |
{ | |
$DN = $_.'[DN]' | |
$Identifier = $_.'[Identifier]' | |
$ObjectType = $_.'[ObjectType]' | |
# Get full CS Object (for $targetName, email and mobile to persist through API errors) | |
$MAName = "xMatters" | |
$csObj = Get-CSObject -DN $DN -MA $MAName | |
$mvObj = Get-MVObject -ID $csObj.MvGuid.Guid | |
$targetName = $mvObj.Attributes.accountName.Values.ValueString | |
$mobile = $mvObj.Attributes.mobilePhoneE164.Values.ValueString | |
$mobileID = $mvObj.Attributes.xMattersPhoneID.Values.ValueString | |
$email = $mvObj.Attributes.mail.Values.ValueString | |
$emailID = $mvObj.Attributes.xMattersEmailID.Values.ValueString | |
# Update/Add Object | |
$xMattersBody = @{} | |
foreach ($can in $_.'[ChangedAttributeNames]') | |
{ | |
"=======================================================" | out-file $DebugFile -append | |
Write-output "Changed Attrib: $can" | out-file $DebugFile -append | |
if ( $can -eq 'firstName'){$firstName = $_.'firstName'; $xMattersBody.Add("firstName",$firstName)} | |
if ( $can -eq 'lastName'){$lastName = $_.'lastName'; $xMattersBody.Add("lastName",$lastName)} | |
if ( $can -eq 'timezone'){$timezone = $_.'timezone'; $xMattersBody.Add("timezone",$timezone)} | |
if ( $can -eq 'weblogin'){$weblogin = $_.'weblogin'; $xMattersBody.Add("weblogin",$weblogin)} | |
if ( $can -eq 'language'){$language = $_.'language'; $xMattersBody.Add("language",$language)} | |
if ( $can -eq 'siteName'){$siteName = $_.'siteName'} | |
if ( $can -eq 'siteID'){$siteID = $_.'siteID'} | |
#SiteID and SiteName | |
if (($siteID) -and ($siteName)){ | |
$xMattersSiteBody = @{} | |
$xMattersSiteBody.Add("id",$DN) | |
$xMattersSiteBody.Add("site", @{id = $($siteID); name = $($siteName)}) | |
"SiteID and SiteName obtained from changed attributes for $($targetName)" | Out-File $DebugFile -Append | |
"SiteID: $($siteID) SiteName: $($siteName)" | Out-File $DebugFile -Append | |
$blnSiteUpdate = $true | |
} else { | |
$blnSiteUpdate = $false | |
} | |
# Only Site ID or Site Name retreived from changed attributes | |
# Retreive missing and update | |
if ((!$blnSiteUpdate) -and (($siteID) -or ($siteName))){ | |
if (!$siteID) { | |
$siteID = $mvObj.Attributes.officeLocationID.Values.ValueString | |
"SiteID $($siteID) retreived from MV" | Out-File $DebugFile -Append | |
} | |
if (!$siteName) { | |
$siteName = $mvObj.Attributes.officeLocation.Values.ValueString | |
"SiteName $($siteName) retreived from MV" | Out-File $DebugFile -Append | |
} | |
if (($siteID) -and ($siteName)){ | |
$xMattersSiteBody = @{} | |
$xMattersSiteBody.Add("id",$DN) | |
$xMattersSiteBody.Add("site", @{id = $($siteID); name = $($siteName)}) | |
"SiteID $($siteID) and SiteName $($siteName) added to update body for $($targetName)" | Out-File $DebugFile -Append | |
$blnSiteUpdate = $true | |
} else { | |
$blnSiteUpdate = $false | |
} | |
} | |
} # Changed Attributes | |
# Update User | |
if ($_.'[ObjectModificationType]' -eq 'Replace') { | |
# Update Site | |
if ($blnSiteUpdate){ | |
UpdateUser $xMattersSiteBody | |
if ($return){ | |
$blnUserUpdate = $true | |
"Successfully updated xMatters Site for User $($targetName)" | Out-File $DebugFile -Append | |
returnSuccess | |
}else{ | |
$blnUserUpdate = $false | |
"Failed to update xMatters Site for User $($targetName)" | Out-File $DebugFile -Append | |
($xMattersBody | ConvertTo-Json) | Out-File $DebugFile -Append | |
returnError | |
} | |
} | |
# Any Updates for naming etc ? | |
if (!$xMattersBody.Count.Equals(0)){ | |
# Add in ID | |
$xMattersBody.Add("id",$DN) | |
UpdateUser $xMattersBody | |
if ($return){ | |
$blnUserUpdate = $true | |
"Updated User $($targetName)" | Out-File $DebugFile -Append | |
returnSuccess | |
}else{ | |
$blnUserUpdate = $false | |
"Failed to updated User $($targetName)" | Out-File $DebugFile -Append | |
($xMattersBody | ConvertTo-Json) | Out-File $DebugFile -Append | |
returnError | |
} | |
} | |
# Device Updates | |
# ********EMAIL and PHONE*********** | |
# 1. User has no existing device. Create new Device | |
# 2. User has a device and it's changed. Remove old and create new | |
# 3. Users device has been removed. Delete Device | |
# ******************* | |
# Devices | |
if ( $can -eq 'workMobile'){ | |
# Set value either way to capture removal of phone numbers | |
if ($mobile){$workMobile = $mobile}else{$workMobile = $null} | |
$xMattersMobileDeviceBody = @{ | |
recipientType = "DEVICE"; | |
deviceType = "TEXT_PHONE"; | |
phoneNumber = $workMobile; | |
name = "SMS Phone"; | |
owner = $DN | |
} | |
if ($mobileID){$xMattersMobileDeviceBody.Add("id",$mobileID)} | |
# Device Mobile UPDATE | |
if ($xMattersMobileDeviceBody.Count -gt 0){ | |
if ($xMattersMobileDeviceBody.phoneNumber){ | |
# Mobile Device Update | |
DeviceExists $targetName "SMS Phone" | |
if ($return){$blnDevice = $true; $deviceID = $return.id}else{$blnDevice = $false} | |
# User has a Device. If it is different delete so the new one can be added | |
# Modify is unreliable. | |
if ($return.phoneNumber -ne $xMattersMobileDeviceBody.phoneNumber) { | |
"We need to update users phone number from $($return.phoneNumber) to $($xMattersMobileDeviceBody.phoneNumber)" | Out-File $DebugFile -Append | |
if ($blnDevice){ | |
DeleteDeviceByID $deviceID | |
if ($return){$blnDelete = $true}else{$blnDelete = $false} | |
} else { | |
$blnDelete = $false | |
} | |
} else { | |
"Phone numbers already match. xMatters: $($return.phoneNumber) MIM MV: $($xMattersMobileDeviceBody.phoneNumber)" | Out-File $DebugFile -Append | |
returnSuccess | |
} | |
# User does not have a Device, new create Leave Owner and remove ID if it exists, then create | |
if ((!$blnDevice) -or $blnDelete ){ | |
if ($xMattersMobileDeviceBody.id){$xMattersMobileDeviceBody.Remove("id")} | |
UpdateDevice $xMattersMobileDeviceBody | |
if ($return){ | |
$blnUpdate = $true | |
returnSuccess | |
}else{ | |
$blnUpdate = $false | |
returnError | |
"Failed to update phone number" | Out-File $DebugFile -Append | |
($xMattersMobileDeviceBody | ConvertTo-Json) | Out-File $DebugFile -Append | |
} | |
} | |
} else { | |
# Phone number empty | |
# Remove Device | |
DeviceExists $targetName "SMS Phone" | |
if ($return){$blnDevice = $true; $deviceID = $return.id}else{$blnDevice = $false} | |
# User has a Device, delete it then add a new one was Modify isn't reliable | |
if ($blnDevice){ | |
DeleteDeviceByID $deviceID | |
if ($return){$blnDelete = $true}else{$blnDelete = $false} | |
if ($blnDelete){ | |
returnSuccess | |
"Successfully deleted phone number" | Out-File $DebugFile -Append | |
} else { | |
returnError | |
"Failed to delete phone number" | Out-File $DebugFile -Append | |
} | |
} | |
} | |
} | |
} | |
if ( $can -eq 'email'){ | |
# Set value either way to capture removal of email address | |
if (!$email){$email = $null} | |
$xMattersEmailDeviceBody = @{ | |
recipientType = "DEVICE"; | |
deviceType = "EMAIL"; | |
emailAddress = $email; | |
name = "Work Email"; | |
owner = $DN | |
} | |
if ($emailID){$xMattersEmailDeviceBody.Add("id",$emailID)} | |
if ($xMattersEmailDeviceBody.Count -gt 0){ | |
if ($xMattersEmailDeviceBody.emailAddress){ | |
# Email Device Update | |
DeviceExists $targetName "Work Email" | |
if ($return){$blnDevice = $true; $deviceID = $return.id}else{$blnDevice = $false} | |
# User has a Device. If it is different delete so the new one can be added | |
# Modify is unreliable. | |
if ($return.emailAddress -ne $xMattersEmailDeviceBody.emailAddress){ | |
"We need to update users email address from $($return.emailAddress) to $($xMattersEmailDeviceBody.emailAddress)" | Out-File $DebugFile -Append | |
if ($blnDevice){ | |
DeleteDevicebyID $deviceID | |
if ($return){$blnDelete = $true}else{$blnDelete = $false} | |
} else { | |
$blnDelete = $false | |
} | |
} else { | |
"Email address is correct. xMatters: $($return.emailAddress) MIM MV: $($xMattersEmailDeviceBody.emailAddress)" | Out-File $DebugFile -Append | |
returnSuccess | |
} | |
# User does not have a Device, new create Leave Owner and remove ID if it exists, then create | |
if ((!$blnDevice) -or $blnDelete ){ | |
if ($xMattersEmailDeviceBody.id){$xMattersEmailDeviceBody.Remove("id")} | |
UpdateDevice $xMattersEmailDeviceBody | |
if ($return){ | |
$blnUpdate = $true | |
returnSuccess | |
"Successfully updated email address" | Out-File $DebugFile -Append | |
}else { | |
$blnUpdate = $false | |
returnError | |
"Failed to update email address" | Out-File $DebugFile -Append | |
($xMattersEmailDeviceBody | ConvertTo-Json) | Out-File $DebugFile -Append | |
} | |
} | |
} else { | |
# Remove Email Address | |
DeviceExists $targetName "Work Email" | |
if ($return){$blnDevice = $true; $deviceID = $return.id}else{$blnDevice = $false} | |
# User has a Device, delete it then add a new one was Modify isn't reliable | |
if ($blnDevice){ | |
DeleteDevicebyID $deviceID | |
if ($return){$blnDelete = $true}else{$blnDelete = $false} | |
if ($blnDelete){ | |
returnSuccess | |
"Successfully deleted email address" | Out-File $DebugFile -Append | |
}else { | |
returnError | |
"Failed to delete email address" | Out-File $DebugFile -Append | |
} | |
} | |
} | |
} | |
} | |
} | |
# Add User | |
if ($_.'[ObjectModificationType]' -eq 'Add') { | |
"Add User Export : " + $targetName | Out-File $DebugFile -Append | |
$xMattersBody | Out-File $DebugFile -Append | |
$xMattersBody.Add("roles", @("Standard User")) | |
# note if no site ID (user has no officelocation, they will end up in the Default Site) | |
if (($siteID) -and ($siteName)){ | |
$xMattersBody.Add("site", @{id = $($siteID); name = $($siteName)}) | |
} | |
try { | |
$createNewUser = Invoke-RestMethod -Uri ($xMattersBaseURI + $xMattersCreateUsersURI) -Headers @{Authorization = "Basic $Site_EncodedAuth"} -method POST -ContentType 'application/json;charset=UTF-8' -body ($xMattersBody | convertto-json) -TimeoutSec $Global:apiTimeout -ErrorAction SilentlyContinue | |
} | |
catch { | |
if ($createNewUser){ | |
# Success | |
$createNewUser = $null | |
returnSuccess | |
} else { | |
"Problem creating user $($targetName) " | Out-File $DebugFile -Append | |
"**Error Status Code** " + $_.Exception.Response.StatusCode.value__ | Out-File $DebugFile -Append | |
"**Error Status Description** " + $_.Exception.Response.StatusDescription | Out-File $DebugFile -Append | |
($xMattersBody | convertto-json) | Out-File $DebugFile -Append | |
returnError | |
} | |
} | |
# Device Add EMAIL | |
if (!$xMattersEmailDeviceBody.Count.Equals(0)){ | |
try { | |
$newUserEmail = Invoke-RestMethod -Uri ($xMattersBaseURI + $createDeviceURI) -Headers @{Authorization = "Basic $Site_EncodedAuth"} -method POST -ContentType 'application/json;charset=UTF-8' -body ($xMattersEmailDeviceBody | convertto-json) -TimeoutSec $Global:apiTimeout -ErrorAction SilentlyContinue | |
} | |
catch { | |
if ($newUserEmail){ | |
# Success | |
$newUserEmail = $null | |
returnSuccess | |
} else { | |
"Problem creating user device (email) $($targetName)" | Out-File $DebugFile -Append | |
"**Error Status Code** " + $_.Exception.Response.StatusCode.value__ | Out-File $DebugFile -Append | |
"**Error Status Description** " + $_.Exception.Response.StatusDescription | Out-File $DebugFile -Append | |
($xMattersEmailDeviceBody | convertto-json) | Out-File $DebugFile -Append | |
returnError | |
} | |
} | |
} | |
# Device Add Mobile | |
if (!$xMattersMobileDeviceBody.Count.Equals(0)){ | |
try { | |
$newUserMobile = Invoke-RestMethod -Uri ($xMattersBaseURI + $createDeviceURI) -Headers @{Authorization = "Basic $Site_EncodedAuth"} -method POST -ContentType 'application/json;charset=UTF-8' -body ($xMattersMobileDeviceBody | convertto-json) -TimeoutSec $Global:apiTimeout -ErrorAction SilentlyContinue | |
} | |
catch { | |
if ($newUserMobile){ | |
# Success | |
$newUserMobile = $null | |
returnSuccess | |
} else { | |
"Problem creating user device (mobile) $($targetName)" | Out-File $DebugFile -Append | |
"**Error Status Code** " + $_.Exception.Response.StatusCode.value__ | Out-File $DebugFile -Append | |
"**Error Status Description** " + $_.Exception.Response.StatusDescription | Out-File $DebugFile -Append | |
($xMattersMobileDeviceBody | convertto-json) | Out-File $DebugFile -Append | |
returnError | |
} | |
} | |
} | |
} | |
# Delete User | |
if ($_.'[ObjectModificationType]' -eq 'Delete') { | |
"Delete User Export : " + $_.targetName | Out-File $DebugFile -Append | |
$DN | Out-File $DebugFile -Append | |
try { | |
$deleteUser = Invoke-RestMethod -Uri ($xMattersBaseURI + $xMattersCreateUsersURI +"/"+$DN) -Headers @{Authorization = "Basic $Site_EncodedAuth"} -method Delete -ContentType 'application/json;charset=UTF-8' -TimeoutSec $Global:apiTimeout -ErrorAction SilentlyContinue | |
} | |
catch { | |
if ($deleteUser){ | |
# Success | |
returnSuccess | |
$deleteUser = $null | |
} else { | |
"Problem deleting user $($targetName)" | Out-File $DebugFile -Append | |
"**Error Status Code** " + $_.Exception.Response.StatusCode.value__ | Out-File $DebugFile -Append | |
"**Error Status Description** " + $_.Exception.Response.StatusDescription | Out-File $DebugFile -Append | |
returnError | |
} | |
} | |
} | |
"=======================================================" | out-file $DebugFile -append | |
$csObj = $null | |
$mvObj = $null | |
$targetName = $null | |
$mobile = $null | |
$email = $null | |
$emailID = $null | |
$mobileID = $null | |
$siteID = $null | |
$site = $null | |
} # END PROCESS | |
END | |
{ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment