Мы запускаем скрипт powershelll для обновления атрибутов LDAP из Servicenow. Ниже приведена ошибка.
Access Request Console : LDAP Script Directory : C:\MID Server INT\agent\scripts\PowerShell
Object DN : employeeNumber=L1009804,ou=people,ou=partenaires,dc=total,dc=com
Exception : The running command stopped because the preference variable "ErrorActionPreference" or common parameter is set to Stop: At C:\MID Server INT\agent\scripts\PowerShell\LDAP\ldapFunctions.psm1:14 char:1
+ {
+ ~
Missing closing '}' in statement block or type definition.
At C:\MID Server INT\agent\scripts\PowerShell\LDAP\ldapFunctions.psm1:58 char:2
+ }
+ ~
Unexpected token '}' in expression or statement.
At C:\MID Server INT\agent\scripts\PowerShell\LDAP\ldapFunctions.psm1:60 char:1
+ }
+ ~
Unexpected token '}' in expression or statement. .
Ниже приведен скрипт Powershell, который запускается при запросе на поднятие и запускается через рабочий процесс. Приток данных работает правильно, но у нас есть проблема при передаче из ServiceNow в LDAP. Сценарий не выполняется при каждом запуске.
<#
.Synopsis
Create a new LdapConnection
.EXAMPLE
New-LdapConnection -LDAPServer 127.0.0.1 -Login admin -Password password1
Description
-----------
Create a new LdapConnection on 127.0.0.1 server with admin credential
#>
[void][System.Reflection.Assembly]::LoadWithPartialName("System.DirectoryServices.Protocols")
function New-LdapConnection
{
[OutputType([System.DirectoryServices.Protocols.LDAPConnection])]
Param
(
# Description d'aide LDAPServer
[String] $LDAPServer,
# Description d'aide LDAPServerPort
[Int32] $LDAPServerPort=389,
# Description d'aide Login
[String] $Login,
# Description d'aide Password
[String] $Password,
# Description d'aide AuhtenticationType
[String] $AuhtenticationType="Basic",
# Description d'aide ProtocolVersion
[int] $ProtocolVersion=3,
# Description d'aide SecureSocketLayer
[Boolean] $SecureSocketLayer=$true,
# Description d'aide EncryptionType
[int] $EncryptionType=0
)
Process
{
#$LDAPServer = $ldapURL
$Credentials = New-Object System.Net.NetworkCredential($Login,$Password)
$LDAPConnection = New-Object System.DirectoryServices.Protocols.LDAPConnection($LDAPServer,$Credentials,$AuhtenticationType)
$LDAPConnection.SessionOptions.ProtocolVersion = $ProtocolVersion
$LDAPConnection.SessionOptions.SecureSocketLayer =$SecureSocketLayer
# don't check certificate (feature enabled again on 24/11/2016 as requested by customer)
$LDAPConnection.SessionOptions.VerifyServerCertificate = {
param(
[DirectoryServices.Protocols.LdapConnection]$Connection,
[Security.Cryptography.X509Certificates.X509Certificate2]$Certificate
)
$Global:LdapCertificate = $Certificate
return $true
}
$LDAPConnection.Bind()
return $LDAPConnection
}
}
<#
.Synopsis
Find a Entry in LDAP
.EXAMPLE
Find-LdapEntry -LdapConnection $con -filter "(objectClass=person)" -rootDistinguishedName "DC=test,DC=lab"
#>
function Find-LdapEntry
{
[OutputType([System.DirectoryServices.Protocols.SearchResultEntry])]
Param
(
# Ldap Connection
[Parameter(Mandatory=$true)]
[System.DirectoryServices.Protocols.LDAPConnection] $LdapConnection,
# Ldap Filter
[Parameter(Mandatory=$true)]
[String] $filter,
# Base DN
[Parameter(Mandatory=$true)]
[String] $rootDistinguishedName
)
Process
{
Write-Host "Begin Find Entry"
$Filter = $filter
$TimeOut = New-Object System.TimeSpan(1,0,0)
$Request = New-Object System.DirectoryServices.Protocols.SearchRequest($rootDistinguishedName, $Filter, "Subtree", $null)
$Response = $LdapConnection.SendRequest($Request,$TimeOut)
if($Response.Entries.Count -gt 0){
$Entry = $Response.Entries[0]
}else{
$Entry = $null
}
return $Entry
}
}
<#
.Synopsis
Add a Entry in LDAP
.EXAMPLE
New-LdapAddRequest -LdapConnection $con -Attrib $attrib -ObjectDN $obj_dn
#>
function New-LdapAddRequest
{
Param
(
# Ldap Connection
[Parameter(Mandatory=$true)]
[System.DirectoryServices.Protocols.LDAPConnection] $LdapConnection,
# Attributes to Add
[Parameter(Mandatory=$true)]
[System.Collections.Hashtable] $Attrib,
# Object DN
[Parameter(Mandatory=$true)]
[String] $ObjectDN
)
Process
{
[string[]]$result = @()
[string[]] $newObjClass = @()
$newObjClass = $Attrib.Get_Item("defaultobjclass").split("^") | where {$_ -ne "^"}
Write-Host "Begin New-LdapAddRequest"
$newEntry = (new-object "System.DirectoryServices.Protocols.AddRequest")
$newEntry.DistinguishedName = $ObjectDN
if($Attrib.Get_Item("objectclass") -ne $null -and $Attrib.Get_Item("objectclass") -ne ""){
$objcl = $Attrib.Get_Item("objectclass")
$objs = $objcl.split("^") | where {$_ -ne "^"}
foreach($i in $objs){
$newObjClass += $i
}
}
Write-Host "Create new entry ", $ObjectDN, " with class ", $newObjClass
$attrObjClass = New-Object System.DirectoryServices.Protocols.DirectoryAttribute("objectclass",$newObjClass)
$newEntry.Attributes.Add($attrObjClass)
#add values of the attribute
foreach ($line in $Attrib.GetEnumerator()) {
$key = $($line.Name)
$val = $($line.Value)
if($key -ne "DN" -and $key -ne "objectclass" -and $key -ne "defaultobjclass"){
Write-Host "Key : ", $key ," ; Value : ", $val
if( $val.Contains("^") ){
[string[]] $tab = @()
$tab = $val.split("^") | where {$_ -ne "^"}
$attr = New-Object System.DirectoryServices.Protocols.DirectoryAttribute($key, $tab)
}else{
$attr = New-Object System.DirectoryServices.Protocols.DirectoryAttribute( $key, $val)
}
$newEntry.Attributes.Add($attr)
}
}
$re = $LdapConnection.SendRequest($newEntry)
#$result += "NewEntry_ResultCode: $($re.ResultCode)"
if ($re.ResultCode -ne [System.directoryServices.Protocols.ResultCode]::Success){
Write-Host "NewEntry_ErrorMessage: $($re.ResultCode.ErrorMessage)"
throw "$($re.ResultCode.ErrorMessage)"
}
#return $result
}
}
<#
.Synopsis
Update access for an object in LDAP
.EXAMPLE
New-LdapUpdateRequest -LdapConnection $connexion -Entry $Entry -AttribToUpd $hashAttrUpd -AttribToDlt $hashAttrDlt
#>
function New-LdapUpdateRequest
{
Param
(
# Ldap Connection
[Parameter(Mandatory=$true)]
[System.DirectoryServices.Protocols.LDAPConnection] $LdapConnection,
# Entry Profile
[Parameter(Mandatory=$true)]
[System.DirectoryServices.Protocols.SearchResultEntry] $Entry,
# Attributes to Modify
[System.Collections.Hashtable] $AttribToUpd,
# Attributes to Delete
[System.Collections.Hashtable] $AttribToDlt
)
Process
{
if ($AttribToUpd -ne $null) {
$reUpt = New-LdapModifyRequest -LdapConnection $LdapConnection -Entry $Entry -Attrib $AttribToUpd
}
if ($AttribToDlt -ne $null) {
$reDlt = New-LdapDeleteRequest -LdapConnection $LdapConnection -Entry $Entry -AttribToDelete $AttribToDlt
}
}
}
<#
.Synopsis
Delete a Entry in LDAP
.EXAMPLE
New-LdapDeleteRequest -LdapConnection $con -Entry $Entry -AttribToDelete $attrib
#>
function New-LdapDeleteRequest
{
# [OutputType([System.DirectoryServices.Protocols.DirectoryResponse])]
Param
(
# Ldap Connection
[Parameter(Mandatory=$true)]
[System.DirectoryServices.Protocols.LDAPConnection] $LdapConnection,
# Entry Profile
[Parameter(Mandatory=$true)]
[System.DirectoryServices.Protocols.SearchResultEntry] $Entry,
# Attributes to delete
[Parameter(Mandatory=$true)]
[System.Collections.Hashtable] $AttribToDelete
)
Process
{
$r = (new-object "System.DirectoryServices.Protocols.ModifyRequest")
$r.DistinguishedName = $Entry.DistinguishedName
foreach($attrib in $AttribToDelete.GetEnumerator()){
$key = $($attrib.Name)
$val = $($attrib.Value)
if($key -ne "objectclass" -and $Entry.Attributes[$key] -ne $null ){
if ($val -eq "" -or $val -eq $null){
Write-Host "Delete attribute : ", $key
$ope = New-Object "System.DirectoryServices.Protocols.DirectoryAttributeModification"
$ope.Name = $key
$ope.Operation = [System.DirectoryServices.Protocols.DirectoryAttributeOperation]::Delete
$r.Modifications.Add($ope)
}
}
}
$ObjClassVal = $AttribToDelete.Get_Item("objectClass")
if($ObjClassVal -ne $null){
# process objectClass when provided
[string[]] $DelObjClassValue = @()
$DelObjClassValue = $ObjClassVal.split("^") | where {$_ -ne "^"}
if(!$Entry.Attributes["objectclass"].GetValues([string]).Contains($DelObjClassValue[0])){
Write-Host "The entry does not have that objectClass"
}else{
$tabObjClass = $Entry.Attributes["objectclass"].GetValues([string])
Write-Host "Object Class : ", $tabObjClass
[string[]] $newObjClass = @()
foreach($i in $tabObjClass){
$validValue = $true
foreach($j in $DelObjClassValue){
if($i -eq $j){
$validValue = $false
}
}
if($validValue -eq $true){
$newObjClass += $i
}
}
Write-Host "New Object Class : ", $newObjClass
}
#prepare the request
$objclass = New-Object "System.DirectoryServices.Protocols.DirectoryAttributeModification"
$objclass.Name = "objectclass"
$objclass.Operation = [System.DirectoryServices.Protocols.DirectoryAttributeOperation]::Replace
$objclass.AddRange($newObjClass)
$r.Modifications.Add($objclass)
}
#Actually process the request through the server
$re = $LDAPConnection.SendRequest($r);
if ($re.ResultCode -ne [System.directoryServices.Protocols.ResultCode]::Success){
Write-Host "SendRequest ResultCode : $($re.ResultCode) ; ErrorMessage : $($re.ResultCode.ErrorMessage)"
throw "$($re.ResultCode.ErrorMessage)"
}
}
}
<#
.Synopsis
Create access for a Entry in LDAP
.EXAMPLE
New-LdapModifyRequest -LdapConnection $con -Entry $Entry -Attrib $attrib
#>
function New-LdapModifyRequest
{
Param
(
# Ldap Connection
[Parameter(Mandatory=$true)]
[System.DirectoryServices.Protocols.LDAPConnection] $LdapConnection,
# Entry Profile
[Parameter(Mandatory=$true)]
[System.DirectoryServices.Protocols.SearchResultEntry] $Entry,
# Attributes to Add
[Parameter(Mandatory=$true)]
[System.Collections.Hashtable] $Attrib
)
Process
{
Write-Host "Begin Update LdapModifyRequest for", $Entry.DistinguishedName
$r = (new-object "System.DirectoryServices.Protocols.ModifyRequest")
$r.DistinguishedName = $Entry.DistinguishedName
$obj = $Attrib.Get_Item("objectclass")
if($obj -ne $null){
# process objectClass when provided
[string[]] $TabObjclass = @()
$TabObjclass = $obj.split("^") | where {$_ -ne "^"}
$getAccess = $false
foreach($line in $TabObjclass){
if($Entry.Attributes["objectclass"].GetValues([string]).Contains($line)){
$getAccess = $true
}
}
if(!$getAccess){
Write-Host "Create Entry - set objectClass"
$newobjclass = New-Object "System.DirectoryServices.Protocols.DirectoryAttributeModification"
$newobjclass.Name = "objectClass"
$newobjclass.Operation = [System.DirectoryServices.Protocols.DirectoryAttributeOperation]::Add
#add values of the attribute
foreach($line in $TabObjclass){
$newobjclass.Add($line)
}
$r.Modifications.Add($newobjclass)
}
}
Write-Host "Update Attributes"
foreach ($line in $Attrib.GetEnumerator()) {
$key = $($line.Name)
$val = $($line.Value)
if ($Entry.Attributes[$key] -or $val) {
if ($key -ne "objectclass" -and $key -ne "defaultobjclass") {
if ($Entry.Attributes[$key]){
Write-Host " Key : ", $key ," ; New Value : ", $val ," ; LDAP Value : ", $Entry.Attributes[$key].GetValues([string])
}else{
Write-Host " Key : ", $key ," ; New Value : ", $val ," ; LDAP Value : EMPTY "
}
$attr = New-Object "System.DirectoryServices.Protocols.DirectoryAttributeModification"
$attr.Name = $key
if($Entry.Attributes[$key]){
$attr.Operation = [System.DirectoryServices.Protocols.DirectoryAttributeOperation]::Replace
}else{
$attr.Operation = [System.DirectoryServices.Protocols.DirectoryAttributeOperation]::Add
}
if($val -Match "\^"){
[string[]] $tab = @()
$tab = $val.split("^") | where {$_ -ne "^"}
$attr.AddRange($tab)
}else{
$attr.Add($val)
}
$r.Modifications.Add($attr)
}
}
}
#Actually process the request through the server
$re = $LdapConnection.SendRequest($r);
if ($re.ResultCode -ne [System.directoryServices.Protocols.ResultCode]::Success){
Write-Host "SendRequest ResultCode : $($re.ResultCode) ; ErrorMessage : $($re.ResultCode.ErrorMessage)"
throw "$($re.ResultCode.ErrorMessage)"
}
}
}
<# AMO 18/08/2017 Nouvelle fonction pour la suppression de l'entrée
.Synopsis
Delete an object in LDAP
.EXAMPLE
New-LdapDeleteRecord -LdapConnection $connexion -Entry $Entry
#>
function New-LdapDeleteRecord
{
Param
(
# Ldap Connection
[Parameter(Mandatory=$true)]
[System.DirectoryServices.Protocols.LDAPConnection] $LdapConnection,
# Entry Profile
[Parameter(Mandatory=$true)]
[System.DirectoryServices.Protocols.SearchResultEntry] $Entry
)
Process
{
Write-Host "New-LdapDeleteRecord Begin"
#AMO 18/08/2017 Suppression de l'entrée
$r = (new-object "System.DirectoryServices.Protocols.DeleteRequest")
$r.DistinguishedName = $Entry.DistinguishedName
Write-Host "New-LdapDeleteRecord sendRequest"
#Actually process the request through the server
$re = $LdapConnection.SendRequest($r);
if ($re.ResultCode -ne [System.directoryServices.Protocols.ResultCode]::Success){
Write-Host "SendRequest ResultCode : $($re.ResultCode) ; ErrorMessage : $($re.ResultCode.ErrorMessage)"
throw "$($re.ResultCode.ErrorMessage)"
}
Write-Host "New-LdapDeleteRecord End"
}
}
<#
.Synopsis
Transform a Json to HashTable
.EXAMPLE
Format-JsonToHashtable -JsonString $jsonStr
#>
function Format-JsonToHashtable
{
[OutputType([System.Collections.Hashtable])]
Param
(
# Entry Profile
[Parameter(Mandatory=$true)]
[String] $JsonString
)
Process
{
$jsonConv = $JsonString -replace "\\", ""
$jsonObject = $jsonConv | ConvertFrom-Json
foreach ($myPsObject in $jsonObject) {
$hashAttrJson = @{}
$myPsObject | Get-Member -MemberType *Property | % {
$hashAttrJson.($_.name) = $myPsObject.($_.name)
}
}
return $hashAttrJson
}
}