Reputation: 25
We are running powershelll script to update LDAP attributes from Servicenow. We get below error.
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. .
Below is the Powershell script, which is triggered on raising request and is triggered via workflow. Data Inflow is working correctly but we have issue while outgoing from ServiceNow to LDAP . Script fails on every run.
<#
.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
}
}
Upvotes: 2
Views: 983
Reputation: 13483
I believe the error is here:
$LDAPConnection.SessionOptions.VerifyServerCertificate = {
param(
[DirectoryServices.Protocols.LdapConnection]$Connection,
[Security.Cryptography.X509Certificates.X509Certificate2]$Certificate
)
$Global:LdapCertificate = $Certificate
return $true
}
You are creating a Script Block with parameters. The problem I believe is that you are not providing any parameters to the script block, and so PowerShell is looking at the subsequent commands to "fill" the parameters, which causes the error.
You will have to pass an -ArgumentList
to "fill" the parameters if you are implementing it like this. e.g.:
$LDAPConnection.SessionOptions.VerifyServerCertificate = {
param(
[DirectoryServices.Protocols.LdapConnection]$Connection,
[Security.Cryptography.X509Certificates.X509Certificate2]$Certificate
)
$Global:LdapCertificate = $Certificate
return $true
} -ArgumentList "Connection", "Certificate"
Upvotes: 2