Last active
November 25, 2020 15:34
-
-
Save brianfgonzalez/f1e9757589b865f5c3d7b4cf0d85c884 to your computer and use it in GitHub Desktop.
Sync USB Devices From ServiceNow to SCCM (using secRMM Console Extension)
This file contains hidden or 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
# ============================================================================ | |
# Module: ServiceNowSecRMMSCCM.ps1 | |
# | |
# Purpose: Call Polypore.net ServiceNow REST API to get | |
# secRMM device ids by region. | |
# | |
# This powershell script is called by a cmd file named ServiceNowSecRMMSCCM.cmd | |
# This powershell script and the cmd file named ServiceNowSecRMMSCCM.cmd | |
# need to be in the same directory | |
# | |
# This script requires Powershell version 3 or better. | |
# | |
# Copyright (c) 2020 Polypore.net | |
# ============================================================================ | |
$Global:SCCMSecRMMPolicyNameFromRegionHash = | |
@{ | |
#ACS = "ACS"; | |
#AKCH = "AKCH"; | |
CLTO = "CLTO" | |
SLTP = "SLTP"; | |
CLTP = "CLTP_TEST"; | |
AKCHSZ = "AKCHSZ"; | |
}; | |
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; | |
$RegionName = "SLTP" | |
$ServiceNowURL = "https://polyporedev.service-now.com/api/now/table/cmdb_ci_acc" | |
$ServiceNowLocationsURL = "https://polyporedev.service-now.com/api/now/table/cmn_location" | |
$ServiceNowUserId = "*****" | |
$ServiceNowPassword = "*****" | |
$SecureServiceNowPassword = ConvertTo-SecureString $ServiceNowPassword -AsPlainText -Force | |
$ServiceNowTag = "serial_number" | |
$secRMMManagedTag = 'u_read_unmanaged_usb' | |
$SecRMMPropertyNameToModify = "AllowedInternalIds" | |
$SCCMConsoleBinDirectory = "C:\Program Files (x86)\Microsoft Configuration Manager\AdminConsole\bin\" | |
$Global:PolicyHasChanged = $false; | |
$Global:SecRMMPropertyValueOld = $null; | |
$Global:SecRMMPropertyValueNew = $null; | |
$Global:ErrorMessage = $null; | |
# ============================================================================ | |
# ServiceNow functions - START | |
# ============================================================================ | |
function CallServiceNowURLRestApi { | |
Param | |
( | |
[string] $ServiceNowURL_in, | |
[string] $ServiceNowUserId_in, | |
[securestring] $SecureServiceNowPassword_in, | |
[string] $strRegion_in | |
) | |
$ServiceNowURLRestApiResponse = $null; | |
if ($null -ne $ServiceNowURL_in) { | |
try { | |
$ServiceNowURLComplete = $ServiceNowURL_in; | |
$ServiceNowURLComplete += "?location=$strRegion_in&u_secrmm=true"; | |
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecureServiceNowPassword_in) | |
$ServiceNowPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) | |
# Build auth header | |
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(('{0}:{1}' -f $ServiceNowUserId_in, $ServiceNowPassword))); | |
# Set proper headers | |
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"; | |
$headers.Add('Authorization', ('Basic {0}' -f $base64AuthInfo)); | |
$headers.Add('Accept', 'application/json'); | |
# Specify HTTP method | |
$method = "get"; | |
Write-Host "Calling ServiceNow...." -ForegroundColor White; | |
# Send HTTP request | |
$ServiceNowURLRestApiResponse = Invoke-RestMethod -Headers $headers -Method $method -Uri $ServiceNowURLComplete; | |
#$ServiceNowURLRestApiResponse.RawContent; | |
Write-Host "Call to ServiceNow succeeded." -ForegroundColor Green; | |
} | |
catch { | |
$ErrorMessage = "CallServiceNowURLRestApi: ERROR: $_"; | |
WriteHostError $ErrorMessage; | |
} | |
} | |
else { | |
$ErrorMessage = "CallServiceNowURLRestApi: ERROR: ServiceNowURL is null"; | |
WriteHostError $ErrorMessage; | |
} | |
return $ServiceNowURLRestApiResponse; | |
} | |
# ============================================================================ | |
function CallSNowIsUsbReadManaged { | |
Param ( | |
[string] $ServiceNowLocationsURL_in, | |
[string] $ServiceNowUserId_in, | |
[securestring] $SecureServiceNowPassword_in, | |
[string] $strRegion_in | |
) | |
#https://polyporedev.service-now.com/api/now/table/cmn_location?sysparm_fields=name&sysparm_limit=10 | |
$SNowIsUsbReadManagedResponse = $null; | |
if ($null -ne $ServiceNowLocationsURL_in) { | |
try { | |
$ServiceNowURLComplete = $ServiceNowLocationsURL_in; | |
$ServiceNowURLComplete += "?sysparm_limit=10&name=$strRegion_in"; | |
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecureServiceNowPassword_in) | |
$ServiceNowPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) | |
# Build auth header | |
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $ServiceNowUserId_in, $ServiceNowPassword))); | |
# Set proper headers | |
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"; | |
$headers.Add('Authorization', ('Basic {0}' -f $base64AuthInfo)); | |
$headers.Add('Accept', 'application/json'); | |
# Specify HTTP method | |
$method = "get"; | |
Write-Host "Calling ServiceNow...." -ForegroundColor White; | |
# Send HTTP request | |
$SNowIsUsbReadManagedResponse = Invoke-RestMethod -Headers $headers -Method $method -Uri $ServiceNowURLComplete; | |
#$ServiceNowURLRestApiResponse.RawContent; | |
Write-Host "Call to ServiceNow succeeded." -ForegroundColor Green; | |
} | |
catch { | |
$ErrorMessage = "CallSNowIsUsbReadManaged: ERROR: $_"; | |
WriteHostError $ErrorMessage; | |
} | |
} | |
else { | |
$ErrorMessage = "CallSNowIsUsbReadManaged: ERROR: ServiceNowLocationsURL_in is null"; | |
WriteHostError $ErrorMessage; | |
} | |
return $SNowIsUsbReadManagedResponse; | |
} | |
# ============================================================================ | |
function GetValuesReturnedFromServiceNow { | |
Param | |
( | |
[string] $strRegion_in, | |
[System.Object] $ServiceNowURLRestApiResponse_in, | |
[string] $ServiceNowTag_in | |
) | |
$CollectionOfValuesFromServiceNow = { }.invoke(); | |
if ($null -ne $ServiceNowURLRestApiResponse_in) { | |
foreach ($record in $ServiceNowURLRestApiResponse_in.result) { | |
#if ($record.location -eq $strRegion_in) { | |
$Value = $record.$ServiceNowTag_in; | |
$CollectionOfValuesFromServiceNow.Add($Value); | |
#} | |
} | |
} | |
#testing, TAKE OUT! | |
#$CollectionOfValuesFromServiceNow.Add("test1"); | |
#$CollectionOfValuesFromServiceNow.Add("9testX"); | |
#$CollectionOfValuesFromServiceNow.Add("Atest4"); | |
#$CollectionOfValuesFromServiceNow.Add("Ztest2"); | |
$Count = $CollectionOfValuesFromServiceNow.Count; | |
Write-Host "Retrieved $Count $ServiceNowTag_in from ServiceNow" -ForegroundColor White; | |
return($CollectionOfValuesFromServiceNow); | |
} | |
# ============================================================================ | |
function GetSCCMSecRMMPolicyNameFromRegion { | |
Param | |
( | |
[string] $Region_in, | |
[System.Object] $ServiceNowURLRestApiResponse_in | |
) | |
#If the region and SCCM policy name are not identical, | |
#then here we will map one to the other... | |
$SCCMSecRMMPolicyName = $Global:SCCMSecRMMPolicyNameFromRegionHash[$Region_in]; | |
if ($null -eq $SCCMSecRMMPolicyName) { | |
$ErrorMessage = "GetSCCMSecRMMPolicyNameFromRegion: ERROR: Lookup for region $Region_in was not found"; | |
WriteHostError $ErrorMessage; | |
} | |
#Write-Output "GetSCCMSecRMMPolicyNameFromRegion is returning $SCCMSecRMMPolicyName as the SCCMSecRMMPolicyName" | |
return($SCCMSecRMMPolicyName); | |
} | |
# ============================================================================ | |
function DoServiceNowWork { | |
Param ( | |
[string] $RegionName_in, | |
[string] $ServiceNowURL_in, | |
[string] $ServiceNowUserId_in, | |
#[string] $ServiceNowPassword_in, | |
[securestring]$SecureServiceNowPassword_in, | |
[string] $ServiceNowTag_in, | |
[string] $secRMMManagedTag_in, | |
[string] $ServiceNowLocationsURL_in | |
) | |
$ErrorLevel = 0; | |
$CollectionOfValuesFromServiceNow = $null; | |
$SCCMSecRMMPolicyName = $null; | |
$ServiceNowURLRestApiResponseJSON = | |
CallServiceNowURLRestApi ` | |
-ServiceNowURL_in $ServiceNowURL_in ` | |
-ServiceNowUserId_in $ServiceNowUserId_in ` | |
-SecureServiceNowPassword_in $SecureServiceNowPassword_in ` | |
-strRegion_in $RegionName_in; | |
$SNowIsUsbReadManagedResponseJSON = | |
CallSNowIsUsbReadManaged ` | |
-ServiceNowLocationsURL_in $ServiceNowLocationsURL_in ` | |
-ServiceNowUserId_in $ServiceNowUserId_in ` | |
-SecureServiceNowPassword_in $SecureServiceNowPassword_in ` | |
-strRegion_in $RegionName_in; | |
if ( | |
($null -ne $ServiceNowURLRestApiResponseJSON) -and | |
($null -ne $SNowIsUsbReadManagedResponseJSON) | |
) | |
{ | |
Write-Host "JSON did return from ServiceNowURLRestApiResponseJSON.." | |
$CollectionOfValuesFromServiceNow = | |
GetValuesReturnedFromServiceNow ` | |
-strRegion_in $RegionName_in ` | |
-ServiceNowURLRestApiResponse_in $ServiceNowURLRestApiResponseJSON ` | |
-ServiceNowTag_in $ServiceNowTag_in; | |
$secRMMManaged = | |
GetValuesReturnedFromServiceNow ` | |
-strRegion_in $RegionName_in ` | |
-ServiceNowURLRestApiResponse_in $SNowIsUsbReadManagedResponseJSON ` | |
-ServiceNowTag_in $secRMMManagedTag_in; | |
Write-Host "Retrieved $secRMMManaged from GetValuesReturnedFromServiceNow" -ForegroundColor White; | |
$SCCMSecRMMPolicyName = | |
GetSCCMSecRMMPolicyNameFromRegion ` | |
-Region_in $RegionName_in ` | |
-ServiceNowURLRestApiResponse_in $ServiceNowURLRestApiResponseJSON; | |
} | |
else { | |
$ErrorLevel = -1; | |
} | |
Write-Host "DoServiceNowWork returning $ErrorLevel"; | |
Write-Host "DoServiceNowWork also returning CollectionOfValuesFromServiceNow $CollectionOfValuesFromServiceNow and SCCMSecRMMPolicyName $SCCMSecRMMPolicyName" | |
$returnObject = [PSCustomObject]@{ | |
ErrorLevel = $ErrorLevel | |
CollectionOfValuesFromServiceNow = $CollectionOfValuesFromServiceNow | |
secRMMManaged = [System.Convert]::ToBoolean($secRMMManaged) | |
SCCMSecRMMPolicyName = $SCCMSecRMMPolicyName | |
} | |
return($returnObject); | |
} | |
# ============================================================================ | |
# SCCM functions - START | |
# ============================================================================ | |
function GetSCCMSiteCode { | |
Param ( | |
) | |
$SCCMSiteCode = $null; | |
try { | |
Import-Module "$($ENV:SMS_ADMIN_UI_PATH)\..\ConfigurationManager.psd1" -Verbose:$False; | |
$SCCMSiteCode = | |
(Get-Item -Path HKLM:SOFTWARE\Microsoft\CCM\CcmEval).GetValue('LastSiteCode'); | |
Write-Host "The SCCM Site Code is $SCCMSiteCode" -ForegroundColor White; | |
} | |
catch { | |
$ErrorMessage = "GetSCCMSiteCode: ERROR: Could not get the SCCM Site Code. $_"; | |
WriteHostError $ErrorMessage; | |
} | |
return($SCCMSiteCode); | |
} | |
# ============================================================================ | |
function ConnectToSCCM { | |
Param | |
( | |
#not used right now but not sure of best approach... | |
[Parameter(Mandatory = $true, Position = 0)] | |
[string] $SCCMSiteCode_in | |
) | |
if (!(Get-Module ConfigurationManager)) { | |
[String]$SCCMInstall = ((Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\ConfigMgr10\Setup').'UI Installation Directory'); | |
Import-Module ($SCCMInstall + 'bin\ConfigurationManager.psd1') -Scope Global; | |
} | |
Set-Location ((get-psdrive -PSProvider CMSite).Name + ":") | |
$SiteCodePath = (Get-Location).Path; | |
if ($null -ne $SiteCodePath) { | |
Write-Host ` | |
"Connected to SCCM $SiteCodePath." -ForegroundColor Green; | |
} | |
else { | |
$ErrorMessage = "ConnectToSCCM: ERROR: Could not connect to SCCM Site Code $SCCMSiteCode_in"; | |
WriteHostError $ErrorMessage; | |
} | |
return($SiteCodePath); | |
} | |
# ============================================================================ | |
function GetSCCMSiteName() { | |
$CMSite = Get-CMSite; | |
$SCCMSiteName = $CMSite.SiteName; | |
Write-Host "The SCCM Site Name is $SCCMSiteName" -ForegroundColor White; | |
return($SCCMSiteName); | |
} | |
# ============================================================================ | |
function GetSCCMSiteServerName() { | |
#$CMSiteServer = Get-CMSiteSystemServer; | |
#$SCCMSiteServerName = $CMSiteServer.NetworkOSPath.replace('\', ''); | |
$SCCMSiteServerName = "CLTHMP601.ad.ak-int.net"; | |
Write-Host "The SCCM Site Server is $SCCMSiteServerName" -ForegroundColor White; | |
return($SCCMSiteServerName); | |
} | |
# ============================================================================ | |
function GetSCCMComplianceBaseline { | |
Param ( | |
[string] $SCCMComplianceBaselineName_in | |
) | |
Write-Host "Searching for the $SCCMComplianceBaselineName_in Baseline" | |
$CMComplianceBase = | |
Get-CMBaseline ` | |
-Name $SCCMComplianceBaselineName_in; | |
if ($null -ne $CMComplianceBase) { | |
Write-Host "Retrieved SCCM Compliance Baseline $SCCMComplianceBaselineName_in" -ForegroundColor Green; | |
} | |
else { | |
$ErrorMessage = "GetSCCMComplianceBaseline: ERROR: Could not retrieve SCCM Compliance Baseline $SCCMComplianceBaselineName_in"; | |
WriteHostError $ErrorMessage; | |
} | |
return($CMComplianceBase); | |
} | |
# ============================================================================ | |
function GetSCCMConfigurationItems { | |
Param ( | |
[string] $SCCMComplianceBaselineName_in | |
) | |
$CMConfigurationItems = | |
Get-CMConfigurationItem ` | |
-Name "$SCCMComplianceBaselineName_in*" ` | |
-ForceWildcardHandling; | |
if ($null -ne $CMConfigurationItems) { | |
$Count = $CMConfigurationItems.Count; | |
Write-Host "Retrieved $Count SCCM ConfigurationItems associated with $SCCMComplianceBaselineName_in (one is parent)" -ForegroundColor Green; | |
} | |
else { | |
$ErrorMessage = "GetSCCMConfigurationItems: ERROR: Could not retrieve SCCM ConfigurationItems associated with $SCCMComplianceBaselineName_in"; | |
WriteHostError $ErrorMessage; | |
} | |
return($CMConfigurationItems); | |
} | |
# ============================================================================ | |
function GetSecRMMPropertyValueWithinLineOfCode { | |
Param ( | |
[string] $LineOfCode_in | |
) | |
$SecRMMPropertyValueWithinLineOfCode = $null; | |
$StartOfValue = | |
$LineOfCode_in.IndexOf('"'); | |
if ($StartOfValue -ne -1) { | |
$EndOfLine = | |
$LineOfCode_in.IndexOf('"', $StartOfValue + 1); | |
if ($EndOfLine -gt $StartOfValue) { | |
$SecRMMPropertyValueWithinLineOfCode = | |
$LineOfCode_in. | |
Substring($StartOfValue + 1, | |
$EndOfLine - $StartOfValue - 1); | |
#Write-Host "SecRMM property value within line of code: $SecRMMPropertyValueWithinLineOfCode"; | |
} | |
else { | |
$ErrorMessage = "GetSecRMMPropertyValueWithinLineOfCode: ERROR: GetSecRMMPropertyValueWithinLineOfCode did not get closing quote: $LineOfCode_in"; | |
WriteHostError $ErrorMessage; | |
} | |
} | |
else { | |
$ErrorMessage = "GetSecRMMPropertyValueWithinLineOfCode: ERROR: GetSecRMMPropertyValueWithinLineOfCode did not get opening quote: $LineOfCode_in"; | |
WriteHostError $ErrorMessage; | |
} | |
return($SecRMMPropertyValueWithinLineOfCode); | |
} | |
# ============================================================================ | |
function GetSecRMMPropertyValueWithinXML { | |
Param ( | |
[string] $XmlNodeText_in | |
) | |
$SecRMMPropertyValue = $null; | |
$CodeThatSetsValueIndex = | |
$XmlNodeText_in. | |
IndexOf("var l_strPropertyValue = "); | |
if ($CodeThatSetsValueIndex -ne -1) { | |
$EndOfLineForCodeThatSetsValueIndex = | |
$XmlNodeText_in. | |
IndexOf("`";", $CodeThatSetsValueIndex); | |
if ($EndOfLineForCodeThatSetsValueIndex -gt $CodeThatSetsValueIndex) { | |
$LineOfCode = | |
$XmlNodeText_in. | |
Substring($CodeThatSetsValueIndex, | |
$EndOfLineForCodeThatSetsValueIndex - | |
$CodeThatSetsValueIndex + | |
1); | |
#Write-Host "Current line of code containing SecRMM property value: $LineOfCode"; | |
$SecRMMPropertyValue = | |
GetSecRMMPropertyValueWithinLineOfCode ` | |
$LineOfCode; | |
} | |
else { | |
$ErrorMessage = "GetSecRMMPropertyValueWithinXML: ERROR: GetSecRMMPropertyValueWithinXML did not get closing semicolon: $XmlNodeText_in"; | |
WriteHostError $ErrorMessage; | |
} | |
} | |
else { | |
$ErrorMessage = "GetSecRMMPropertyValueWithinXML: ERROR: GetSecRMMPropertyValueWithinXML did not get opening line of code: $XmlNodeText_in"; | |
WriteHostError $ErrorMessage; | |
} | |
return($SecRMMPropertyValue) | |
} | |
# ============================================================================ | |
function GetSCCMSecRMMPropertyValue { | |
Param ( | |
[string] $ConfigurationItemSDMPackageXML_in | |
) | |
#Write-Host $ConfigurationItem_in.LocalizedDisplayName -ForegroundColor Red; | |
#Write-Host $ConfigurationItem_in.LocalizedDescription -ForegroundColor Red; | |
$SecRMMPropertyValue = $null; | |
$XmlNamespace = | |
"[namespace-uri()='http://schemas.microsoft.com/SystemsCenterConfigurationManager/2009/07/10/DesiredConfiguration'][1]"; | |
$Xpath = "/*[local-name()='DesiredConfigurationDigest']"` | |
+ $XmlNamespace` | |
+ "/*[local-name()='Application']"` | |
+ $XmlNamespace` | |
+ "/*[local-name()='Settings']"` | |
+ $XmlNamespace` | |
+ "/*[local-name()='RootComplexSetting']"` | |
+ $XmlNamespace` | |
+ "/*[local-name()='SimpleSetting']"` | |
+ $XmlNamespace` | |
+ "/*[local-name()='ScriptDiscoverySource']"` | |
+ $XmlNamespace` | |
+ "/*[local-name()='RemediationScriptBody']"` | |
+ $XmlNamespace; | |
$SDMPackageXML = $ConfigurationItemSDMPackageXML_in; | |
$Xml = New-Object -TypeName System.Xml.XmlDocument | |
$Xml.LoadXml($SDMPackageXML) | |
$XmlNode = Select-Xml -Xml $Xml -Xpath $Xpath; | |
if ($null -ne $XmlNode) { | |
$XmlNodeText = $XmlNode.ToString(); | |
$SecRMMPropertyValue = | |
GetSecRMMPropertyValueWithinXML ` | |
$XmlNodeText; | |
} | |
else { | |
$ErrorMessage = "GetSCCMSecRMMPropertyValue: ERROR: did not get xml node"; | |
WriteHostError $ErrorMessage; | |
} | |
return($SecRMMPropertyValue); | |
} | |
# ============================================================================ | |
function GetSCCMSecRMMPropertyName { | |
Param ( | |
[string] $LocalizedDisplayName_in | |
) | |
$SecRMMPropertyName = $null; | |
$separator = $LocalizedDisplayName_in.IndexOf("-"); | |
if ($separator -ne -1) { | |
$SecRMMPropertyName = | |
$LocalizedDisplayName_in.Substring($separator + 1); | |
$SecRMMPropertyName = $SecRMMPropertyName.Trim(); | |
} | |
return($SecRMMPropertyName); | |
} | |
# ============================================================================ | |
function GetNewSecRMMPropertyValueFromServiceNow { | |
Param ( | |
[string] $SecRMMPropertyValueOld_in, | |
[System.Object] $CollectionOfSecRMMPropertyValues_in | |
) | |
$NewSecRMMPropertyValueFromServiceNow = $null; | |
$index = 0; | |
foreach ($Value in $CollectionOfSecRMMPropertyValues_in) { | |
if ($index -ne 0) { | |
$NewSecRMMPropertyValueFromServiceNow += ";"; | |
} | |
$index++; | |
$NewSecRMMPropertyValueFromServiceNow += | |
$Value; | |
} | |
return($NewSecRMMPropertyValueFromServiceNow); | |
} | |
# ============================================================================ | |
function ProcessSCCMChildConfigurationItem { | |
Param ( | |
[string] $SCCMSecRMMPolicyName_in, | |
[string] $SecRMMPropertyName_in, | |
[System.Object] $CollectionOfSecRMMPropertyValues_in, | |
[System.Object] $SCCMConfigurationItem_in | |
) | |
$SecRMMPropertyName = | |
GetSCCMSecRMMPropertyName ` | |
$SCCMConfigurationItem_in.LocalizedDisplayName; | |
$SecRMMPropertyValue = $null; | |
if ($null -ne $SecRMMPropertyName) { | |
$SecRMMPropertyValue = | |
GetSCCMSecRMMPropertyValue ` | |
$SCCMConfigurationItem_in.SDMPackageXML; | |
if ($SecRMMPropertyName -eq $SecRMMPropertyName_in) { | |
$SecRMMPropertyValueOld = $SecRMMPropertyValue; | |
$SecRMMPropertyValue = | |
GetNewSecRMMPropertyValueFromServiceNow ` | |
$SecRMMPropertyValueOld ` | |
$CollectionOfSecRMMPropertyValues_in; | |
#TESTING, TAKE OUT!!! | |
#$SecRMMPropertyValue = | |
#$(((get-date).ToUniversalTime()).ToString("yyyyMMddTHHmmssZ")); | |
if ($SecRMMPropertyValueOld -ne $SecRMMPropertyValue) { | |
Write-Host "Replace $SecRMMPropertyValueOld with $SecRMMPropertyValue" -ForegroundColor Green; | |
$Global:SecRMMPropertyValueOld = $SecRMMPropertyValueOld; | |
$Global:SecRMMPropertyValueNew = $SecRMMPropertyValue; | |
$Global:PolicyHasChanged = $true; | |
} | |
else { | |
Write-Host "The values in SCCM and ServiceNow are already the same" -ForegroundColor Green; | |
} | |
} | |
else { | |
#Write-Host $ConfigurationItem.LocalizedDisplayName; | |
#Write-Host $ConfigurationItem.LocalizedDescription; | |
} | |
} | |
return($SecRMMPropertyName, $SecRMMPropertyValue); | |
} | |
# ============================================================================ | |
function GetSCCMSecRMMPolicyValues { | |
Param ( | |
[string] $SCCMSecRMMPolicyName_in, | |
[string] $SecRMMPropertyName_in, | |
[System.Object] $CollectionOfSecRMMPropertyValues_in, | |
[System.Object] $SCCMComplianceBaseline_in, | |
[System.Object] $SCCMConfigurationItems_in | |
) | |
$OrderedDictionaryOfSecRMMProperties = [ordered]@{}; | |
Write-Host "SCCM Policy Name based on ServiceNow location: $SCCMSecRMMPolicyName_in"; | |
Write-Host "ServiceNow returned the following value(s) for SCCM secRMM Property: $SecRMMPropertyName_in`:"; | |
foreach ($Value in $CollectionOfSecRMMPropertyValues_in) { | |
Write-Host " $Value"; | |
} | |
#Write-Host $SCCMComplianceBaseline_in.LocalizedDisplayName; | |
foreach ($SCCMConfigurationItem in $SCCMConfigurationItems_in) { | |
if ($SCCMConfigurationItem.IsChild = $false) { | |
#Write-Host $SCCMConfigurationItem.LocalizedDisplayName; | |
#Write-Host $SCCMConfigurationItem.LocalizedDescription; | |
} | |
else { | |
$SecRMMPropertyName, $SecRMMPropertyValue = | |
ProcessSCCMChildConfigurationItem ` | |
$SCCMSecRMMPolicyName_in ` | |
$SecRMMPropertyName_in ` | |
$CollectionOfSecRMMPropertyValues_in ` | |
$SCCMConfigurationItem; | |
if ($null -ne $SecRMMPropertyName) { | |
Write-Host "SecRMM property: $SecRMMPropertyName value: <$SecRMMPropertyValue>"; | |
$OrderedDictionaryOfSecRMMProperties.add( | |
$SecRMMPropertyName, | |
$SecRMMPropertyValue); | |
} | |
} | |
} | |
return($OrderedDictionaryOfSecRMMProperties); | |
} | |
# ============================================================================ | |
function GetPolicyInfo { | |
Param ( | |
[string] $LocalizedDescription_in | |
) | |
$PolicyType = $null; | |
$PolicyDescription = $null; | |
$Array = $LocalizedDescription_in.Split("-") | |
if ($Array.Count -ne 0) { | |
$PolicyDescription = $Array[0]; | |
$Index = | |
$LocalizedDescription_in. | |
IndexOf(" - Computer - Removable Media Policy"); | |
if ($Index -eq -1) { | |
$PolicyType = "User"; | |
} | |
else { | |
$PolicyType = "Computer"; | |
} | |
} | |
$PolicyDescription = $PolicyDescription.Trim(); | |
return($PolicyType, $PolicyDescription); | |
} | |
# ============================================================================ | |
function DoSCCMSaveCallExternalProgram { | |
Param ( | |
[string] $stringConnectedSiteCode_in, | |
[string] $stringServerName_in, | |
[string] $stringSiteName_in, | |
[string] $stringPolicySetName_in, | |
[string] $stringPolicySetType_in, | |
[string] $stringPolicySetDescription_in, | |
[System.Object] $OrderedDictionaryOfProperties_in, | |
[string] $SCCMConsoleBinDirectory_in | |
) | |
$boolSaved = $false; | |
if ($SCCMConsoleBinDirectory_in.EndsWith("\") -eq $false) { | |
$SCCMConsoleBinDirectory_in += "\"; | |
} | |
if ((Test-Path $SCCMConsoleBinDirectory_in) -eq $true) { | |
$AssemblyName = "secRMMSCCM2012ConsoleExtension.dll"; | |
$Assembly = "$SCCMConsoleBinDirectory_in$AssemblyName" | |
#Write-Host $Assembly -ForegroundColor Yellow; | |
if ((Test-Path $Assembly) -eq $true) { | |
$ENV:PATH = "$ENV:PATH;$SCCMConsoleBinDirectory_in"; | |
$ExternalProgram = $PSScriptRoot; | |
$ExternalProgram += "\secRMMSCCM2012ConsoleExtensionExternalInterface.exe"; | |
if ((Test-Path $ExternalProgram) -eq $true) { | |
$TempFileName = $PSScriptRoot + "\tempFile.xml"; | |
$OrderedDictionaryOfProperties_in | | |
Export-Clixml $TempFileName; | |
#$TempFileName | |
$arg1 = "$stringConnectedSiteCode_in"; | |
$arg2 = "$stringServerName_in"; | |
$arg3 = "$stringSiteName_in"; | |
$arg4 = "`"$stringPolicySetName_in`""; | |
$arg5 = "$stringPolicySetType_in"; | |
$arg6 = "`"$stringPolicySetDescription_in`""; | |
$arg7 = "`"$TempFileName`""; | |
$arg8 = "`"$SCCMConsoleBinDirectory_in`""; | |
Write-Host "Calling 32-bit program to perform SCCM save to database (lengthy operation)..." -ForegroundColor Green; | |
#Write-Host $ExternalProgram $arg1 $arg2 $arg3 $arg4 $arg5 $arg6 $arg7 $arg8; | |
#& $ExternalProgram $arg1 $arg2 $arg3 $arg4 $arg5 $arg6 $arg7 $arg8; | |
& $ExternalProgram $arg1 $arg2 $arg3 $arg4 $arg5 $arg6 $arg7 $arg8 2>&1 | Tee-Object -Variable out_content; | |
$boolSaved = $true; | |
} | |
else { | |
$ErrorMessage = "DoSCCMSaveCallExternalProgram: ERROR: Program $ExternalProgram not found"; | |
WriteHostError $ErrorMessage; | |
} | |
} | |
else { | |
$ErrorMessage = "DoSCCMSaveCallExternalProgram: ERROR: Assembly $Assembly not found"; | |
WriteHostError $ErrorMessage; | |
} | |
} | |
else { | |
$ErrorMessage = "DoSCCMSaveCallExternalProgram: ERROR: Directory $SCCMConsoleBinDirectory_in not found"; | |
WriteHostError $ErrorMessage; | |
} | |
return($boolSaved); | |
} | |
# ============================================================================ | |
function DoSCCMSave { | |
Param ( | |
[System.Object] $SCCMComplianceBaseline_in, | |
[string ]$SCCMSiteCode_in, | |
[string ]$SCCMSecRMMPolicyName_in, | |
[System.Object] $OrderedDictionaryOfSecRMMProperties_in, | |
[string] $SCCMConsoleBinDirectory_in | |
) | |
$boolSaved = $false; | |
Write-Host "Starting save to SCCM..." -ForegroundColor Green; | |
$SCCMSiteName = GetSCCMSiteName; | |
$SCCMSiteServerName = GetSCCMSiteServerName; | |
$PolicyType, $PolicyDescription = | |
GetPolicyInfo ` | |
$SCCMComplianceBaseline_in.LocalizedDescription; | |
$boolSaved = | |
DoSCCMSaveCallExternalProgram ` | |
$SCCMSiteCode_in ` | |
$SCCMSiteServerName ` | |
$SCCMSiteName ` | |
$SCCMSecRMMPolicyName_in ` | |
$PolicyType ` | |
$PolicyDescription ` | |
$OrderedDictionaryOfSecRMMProperties_in ` | |
$SCCMConsoleBinDirectory_in; | |
return($boolSaved); | |
} | |
# ============================================================================ | |
function ProcessSCCMSecRMMPolicy { | |
Param ( | |
[string] $SCCMSecRMMPolicyName_in, | |
[string] $SecRMMPropertyName_in, | |
[System.Object] $CollectionOfSecRMMPropertyValues_in, | |
[string] $SCCMConsoleBinDirectory_in, | |
[string] $SCCMSiteCode_in | |
) | |
$ErrorLevel = 0; | |
Write-Host "ProcessSCCMSecRMMPolicy thinks SCCMSecRMMPolicyName_in is $SCCMSecRMMPolicyName_in" | |
# see if there is a baseline created for the sitename | |
$SCCMComplianceBaseline = GetSCCMComplianceBaseline -SCCMComplianceBaselineName_in $SCCMSecRMMPolicyName_in; | |
if ($null -ne $SCCMComplianceBaseline) { | |
# pull configuration items for the specified baseline | |
$SCCMConfigurationItems = GetSCCMConfigurationItems -SCCMComplianceBaselineName_in $SCCMSecRMMPolicyName_in; | |
if ($null -ne $SCCMConfigurationItems) { | |
$OrderedDictionaryOfSecRMMProperties = | |
GetSCCMSecRMMPolicyValues ` | |
-SCCMSecRMMPolicyName_in $SCCMSecRMMPolicyName_in ` | |
-SecRMMPropertyName_in $SecRMMPropertyName_in ` | |
-CollectionOfSecRMMPropertyValues_in $CollectionOfSecRMMPropertyValues_in ` | |
-SCCMComplianceBaseline $SCCMComplianceBaseline ` | |
-SCCMConfigurationItems $SCCMConfigurationItems; | |
$Count = $OrderedDictionaryOfSecRMMProperties.Count; | |
if ($Count -ne 0) { | |
Write-Host "Processing $Count SecRMM properties..."; | |
if ($Global:PolicyHasChanged -eq $true) { | |
$boolSaved = | |
DoSCCMSave ` | |
-SCCMComplianceBaseline_in $SCCMComplianceBaseline ` | |
-SCCMSiteCode_in $SCCMSiteCode_in ` | |
-SCCMSecRMMPolicyName_in $SCCMSecRMMPolicyName_in ` | |
-OrderedDictionaryOfSecRMMProperties_in $OrderedDictionaryOfSecRMMProperties ` | |
-SCCMConsoleBinDirectory_in $SCCMConsoleBinDirectory_in; | |
if ($boolSaved -eq $true) { | |
$ErrorLevel = 0; | |
} else { $ErrorLevel = -7; } | |
} | |
else { | |
Write-Host "No changes have occurred between ServiceNow and SCCM."; | |
$ErrorLevel = 0; | |
} | |
} | |
else { | |
$ErrorLevel = -6; | |
$ErrorMessage = "ProcessSCCMSecRMMPolicy: ERROR: There are $Count SecRMM properties, not saving to SCCM"; | |
WriteHostError $ErrorMessage; | |
} | |
} else { $ErrorLevel = -5; } | |
} else { $ErrorLevel = -4; } | |
return($ErrorLevel); | |
} | |
# ============================================================================ | |
function DoSCCMWork { | |
Param ( | |
[string] $SCCMSecRMMPolicyName_in, | |
[string] $SecRMMPropertyName_in, | |
[System.Object] $CollectionOfSecRMMPropertyValues_in, | |
[string] $SCCMConsoleBinDirectory_in | |
) | |
$ErrorLevel = 0; | |
if ($null -ne $SCCMSecRMMPolicyName_in) { | |
#TODO: Would be nice to figure this out. | |
#Push-Location $PSScriptRoot; | |
#Pop-Location | |
#Remove-Module ConfigurationManager; | |
Write-Host "DoSCCMWork thinks SCCMSecRMMPolicyName_in is $SCCMSecRMMPolicyName_in" | |
$SCCMSiteCode = GetSCCMSiteCode; | |
if ($null -ne $SCCMSiteCode) { | |
$SiteCodePath = ConnectToSCCM($SCCMSiteCode); | |
if ($null -ne $SiteCodePath) { | |
#$CMPSSuppressFastNotUsedCheck = $True; | |
$ErrorLevel = | |
ProcessSCCMSecRMMPolicy ` | |
-SCCMSecRMMPolicyName_in $SCCMSecRMMPolicyName_in ` | |
-SecRMMPropertyName_in $SecRMMPropertyName_in ` | |
-CollectionOfSecRMMPropertyValues_in $CollectionOfSecRMMPropertyValues_in ` | |
-SCCMConsoleBinDirectory_in $SCCMConsoleBinDirectory_in ` | |
-SCCMSiteCode_in $SCCMSiteCode; | |
} else { $ErrorLevel = -3; } | |
} else { $ErrorLevel = -2; } | |
} | |
else { | |
$ErrorLevel = -1; | |
WriteHostError "DoSCCMWork: ERROR: Could not get the SCCM secRMM policy name"; | |
} | |
Write-Host "DoSCCMWork returning $ErrorLevel"; | |
return($ErrorLevel); | |
} | |
# ============================================================================ | |
function LogSecRMMEvent { | |
Param ( | |
[int] $ErrorLevel_in, | |
[string] $RegionName_in, | |
[string] $SCCMSecRMMPolicyName_in, | |
[string] $SecRMMPropertyNameToModify_in | |
) | |
$strSecRMMRegistryPath = "HKLM:\SOFTWARE\Microsoft\MMC\SnapIns\FX:{4bbd4ebc-d808-4efc-b0a6-83c62e4ac931}"; | |
$objSecRMMRegistryKey = Get-ItemProperty -Path $strSecRMMRegistryPath; | |
$strSecRMMPath = $objSecRMMRegistryKey.ApplicationBase; | |
if ((Test-Path $strSecRMMPath) -eq $true) { | |
$computer = "."; | |
$class = "secRMMWMIProvider"; | |
$method = "WriteToNTEventLog"; | |
$namespace = "root/cimv2/secRMM"; | |
$mc = [wmiclass]"\\$computer\ROOT\CIMV2\secRMM:$class"; | |
$mc.PSBase.GetMethodParameters($method); | |
$uint32LogSecRMM = 3; | |
$uint32Log = $uint32LogSecRMM; | |
$strMessage = $null; | |
$EVENTLOG_ERROR_TYPE = 1; | |
$EVENTLOG_INFORMATION_TYPE = 4; | |
$EVENTLOG_TYPE = $null; | |
$Company = "Polypore: "; | |
if ($ErrorLevel_in -eq 0) { | |
$EVENTLOG_TYPE = $EVENTLOG_INFORMATION_TYPE; | |
if ($Global:PolicyHasChanged -eq $true) { | |
#$Global:SecRMMPropertyValueOld = $SecRMMPropertyValueOld; | |
#$Global:SecRMMPropertyValueNew = $SecRMMPropertyValue; | |
#$Global:PolicyHasChanged = $true; | |
$strMessage = "ServiceNow changes occurred in SCCM for region $RegionName_in on property $SecRMMPropertyNameToModify_in`: $Global:SecRMMPropertyValueNew"; | |
} | |
else { | |
$strMessage = "ServiceNow queried but no changes occurred in SCCM for region $RegionName_in on property $SecRMMPropertyNameToModify_in"; | |
} | |
} | |
elseif ($null -ne $Global:ErrorMessage) { | |
$strMessage = $Global:ErrorMessage; | |
$EVENTLOG_TYPE = $EVENTLOG_ERROR_TYPE; | |
} | |
if ($null -ne $strMessage) { | |
$EventId = 302; | |
$strMessage = "$Company $strMessage"; | |
try { | |
Invoke-WmiMethod ` | |
-Class $class ` | |
-Name $method ` | |
-Namespace $namespace ` | |
-ArgumentList ($strMessage, $uint32Log, $EventId, $EVENTLOG_TYPE ) ` | |
-ErrorAction Stop | Out-Null; | |
} | |
catch { | |
$ErrorMessage = "LogSecRMMEvent: ERROR: Could not write event $_"; | |
WriteHostError $ErrorMessage; | |
} | |
} | |
} | |
} | |
# ============================================================================ | |
function WriteHostError { | |
Param ( | |
[string] $ErrorMessage_in | |
) | |
Write-Host $ErrorMessage_in -ForegroundColor Red; | |
$Global:ErrorMessage = $ErrorMessage_in; | |
} | |
# ============================================================================ | |
$doServiceWorkReturn = | |
DoServiceNowWork ` | |
-RegionName_in $RegionName ` | |
-ServiceNowURL_in $ServiceNowURL ` | |
-ServiceNowUserId_in $ServiceNowUserId ` | |
-SecureServiceNowPassword_in $SecureServiceNowPassword ` | |
-ServiceNowTag_in $ServiceNowTag ` | |
-secRMMManagedTag_in $secRMMManagedTag ` | |
-ServiceNowLocationsURL_in $ServiceNowLocationsURL; | |
Write-Host "Main thinks Returned ErrorLevel is $($doServiceWorkReturn.ErrorLevel)" | |
Write-Host "Main thinks CollectionOfSecRMMPropertyValues is $($doServiceWorkReturn.CollectionOfValuesFromServiceNow)" | |
Write-Host "Main thinks secRMMManaged is $($doServiceWorkReturn.secRMMManaged)" | |
Write-Host "Main thinks SCCMSecRMMPolicyName is $($doServiceWorkReturn.SCCMSecRMMPolicyName)" | |
# add [EnforceWhenPluggedIn] prefix if secRMMManaged is True | |
if ($($doServiceWorkReturn.secRMMManaged)) { | |
Write-Host "secRMMManaged is True so lets add the [EnforceWhenPluggedIn] prefix" -ForegroundColor White; | |
#Write-Host ('Lets see the type of CollectionOfValuesFromServiceNow: {0}' -f $($doServiceWorkReturn.CollectionOfValuesFromServiceNow.GetType())) | |
if ($($doServiceWorkReturn.CollectionOfValuesFromServiceNow.Count) -ge 2) | |
{ | |
Write-Host 'CollectionOfValuesFromServiceNow contains multiple USB device they must be combined to a single string' | |
[string]$strCollectionOfValues = $($doServiceWorkReturn.CollectionOfValuesFromServiceNow) -join ';' | |
[string]$strCollectionOfValues = ('[EnforceWhenPluggedIn]{0}' -f $strCollectionOfValues) | |
} else { | |
Write-Host 'CollectionOfValuesFromServiceNow only contains one USB device so no need to combine' | |
[string]$strCollectionOfValues = ('[EnforceWhenPluggedIn]{0}' -f $($doServiceWorkReturn.CollectionOfValuesFromServiceNow)) | |
} | |
Write-Host ('strCollectionOfValues updated: {0}' -f $strCollectionOfValues) -ForegroundColor Yellow; | |
} else { | |
Write-Host "secRMMManaged is False so skip adding the [EnforceWhenPluggedIn] prefix" -ForegroundColor White; | |
if ($($doServiceWorkReturn.CollectionOfValuesFromServiceNow.Count) -ge 2) | |
{ | |
Write-Host 'CollectionOfValuesFromServiceNow contains multiple USB device they must be combined to a single string' | |
[string]$strCollectionOfValues = $($doServiceWorkReturn.CollectionOfValuesFromServiceNow) -join ';' | |
} else { | |
Write-Host 'CollectionOfValuesFromServiceNow only contains one USB device so no need to combine' | |
[string]$strCollectionOfValues = $($doServiceWorkReturn.CollectionOfValuesFromServiceNow) | |
} | |
Write-Host ('strCollectionOfValues updated: {0}' -f $strCollectionOfValues) -ForegroundColor Yellow; | |
} | |
if ($($doServiceWorkReturn.ErrorLevel) -eq 0) { | |
Write-Host "Starting DoSCCMWork..." | |
$ErrorLevel = | |
DoSCCMWork ` | |
-SCCMSecRMMPolicyName_in $($doServiceWorkReturn.SCCMSecRMMPolicyName) ` | |
-SecRMMPropertyName_in $SecRMMPropertyNameToModify ` | |
-CollectionOfSecRMMPropertyValues_in $strCollectionOfValues ` | |
-SCCMConsoleBinDirectory_in $SCCMConsoleBinDirectory; | |
} else { | |
Write-Host "ErrorLevel is $ErrorLevel so there was an issue that prevented the SCCM work from performing" -ForegroundColor Red; | |
} | |
Write-Host "Return from DoSCCMWork is $ErrorLevel" -ForegroundColor Yellow; | |
#LogSecRMMEvent ` | |
# $ErrorLevel ` | |
# $RegionName ` | |
# $SCCMSecRMMPolicyName ` | |
# $SecRMMPropertyNameToModify; | |
#Write-Host "Exiting $ErrorLevel"; | |
#[Environment]::Exit($ErrorLevel); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment