Skip to content

Instantly share code, notes, and snippets.

@darrenjrobinson
Last active November 17, 2018 22:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save darrenjrobinson/eb41e9b3e246cb327ed5e981bfb53e4f to your computer and use it in GitHub Desktop.
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/
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)}
# EMAIL
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