PowerShell OpenLDAP query returns nothing - powershell

I'm trying to retrieve OpenLDAP 2.4 users info.
Connection and bind are OK but request return nothing.
After some investigations, I discovered that there are more than 150 000 records to import. I tried to change $ModelQuery size limit but it didn't change a thing.
What would be the good way to manage this?
$HostName = "ldap.domain.com:389"
$user = 'user'
$Password = ConvertTo-SecureString 'password' -AsPlainText -Force
$pass = [PSCredential]::($user, $Password)
$null = [System.Reflection.Assembly]::LoadWithPartialName("System.DirectoryServices.Protocols")
$LDAPConnect = New-Object System.DirectoryServices.Protocols.LdapConnection "$HostName"
$LDAPConnect.AuthType = [System.DirectoryServices.Protocols.AuthType]::Basic
$LDAPConnect.SessionOptions.ProtocolVersion = 3
try {
$ErrorActionPreference = 'Stop'
$LDAPConnect.Credential = [PSCredential]::($user, $Password)
$ErrorActionPreference = 'Continue'
} catch {
throw "Erreur Bind LDAP - $($_.Exception.Message)"
}
Write-Verbose "Bind LDAP réussi" -Verbose
$BaseDn = 'ou=accounts,dc=domain,dc=com'
$Scope = [System.DirectoryServices.Protocols.SearchScope]::Subtree
$AttrList = $null
$Filter = '(property=staff)'
$ModelQuery = New-Object System.DirectoryServices.Protocols.SearchRequest -ArgumentList $BaseDn, $Filter, $Scope, $AttrList
$ModelQuery.SizeLimit = 10
try {
$ErrorActionPreference = 'Stop'
$ModelRequest = $LDAPConnect.SendRequest($ModelQuery)
$ModelRequest.
$ErrorActionPreference = 'Continue'
} catch {
throw "Probleme de recherche sélection - $($_.Exception.Message)"
}
$ModelRequest.Entries | Export-Csv c:\res.csv

just add variable#() and put entries in it then pipe in csv

Related

Function to check DB in remote server - Timeout question

I am writing a function in PowerShell that will do the following when given some parameter:
Get Credetials to connect to remote SQL Server
Open SQL Connection with given parameters. If Opening connection takes longer than value in $sqlconnectionTimeout, it will report a log file with Timeout error
A query will be introduce in a specific DB from Remote Server. If executing command takes longer than value in $sqlCommandTimeout, it will report a log file with error.
The function will create a html file with connectivity result (True or False). If True, the script will check log reports within last 5 minutes. Connectivity will be True if no logs are found. If False, a log will be created and saved in a specific folder.
About the Timeout variables, No matter what I put in the variable, The Connection is opened and the command is executed. Even If I put 0 forcing it to output a timeout error. The connection is opened and the query executed.
My question is: What am I missing here so that Timeout takes effect when executing the function?
Thanks for your help
This is the Code:
# Editing Variables
$user = "userName"
$DatabaseName = "SampleDB"
$query = "INSERT INTO [SampleDB].[dbo].[HealthChecks]([DateTime],[Source],[User]) VALUES (CURRENT_TIMESTAMP, ##SERVERNAME, CURRENT_USER)"
#Set timeout when stablishing connection (Default = 15)
$sqlConnectionTimeout = 3
#Set timeout when executing sql command (Default = 30)
$sqlCommandTimeout = 3
# 1. R-etrieve the data
function Test-SqlConnection
{
param(
[Parameter(Mandatory)]
[string]$serverURL,
[Parameter(Mandatory)]
[string]$DatabaseName,
[Parameter(Mandatory)]
[string]$user,
[Parameter(Mandatory)]
[string]$query,
[Parameter(Mandatory=$False)]
[string]$sqlConnectionTimeout,
[Parameter(Mandatory=$False)]
[string]$sqlCommandTimeout
)
try
{
$logTime = (Get-Date -Format "hh-mm_dd-MM-yyyy")
$reportPath = "C:\Logs\DBLogs\"
$DBCheckPath = "C:\inetpub\wwwroot\UptimeRobot\"
# Obtain Credentials without revealing password in script
$userName = $user
$passwordFile = "C:\Utilities\keys\password.txt"
$keyFile = "C:\Utilities\keys\aes.key"
$key = Get-Content $keyFile
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $userName, (Get-Content $passwordFile | ConvertTo-SecureString -Key $key)
# Open Connection to DB
$userName = $Credential.UserName
$password = $Credential.GetNetworkCredential().Password
$connectionString = "Data Source={0};database={1};User ID={2};Password={3};Connection Timeout={4}" -f $serverURL,$DatabaseName,$userName,$password,$sqlConnectionTimeout
$sqlConnection = New-Object System.Data.SqlClient.SqlConnection $ConnectionString
$sqlConnection.Open()
#3. P-repare the UpdateRequest
$sqlCommand = New-Object System.Data.SQLClient.SQLCommand
$sqlCommand.CommandTimeout = $sqlCommandTimeout
$sqlCommand.Connection = $sqlConnection
$sqlCommand.CommandText = $query
$res = $sqlCommand.ExecuteNonQuery()
# 4. S-end reports to log file in JSon format
$sqlLogs = Get-Childitem $reportPath -filter *.json | Where-Object {$_.LastWriteTime -gt [datetime]::Now.AddMinutes(-5)}
if($res -eq 1)
{
if($sqlLogs.count -gt 0)
{
$connectivityResult = #{
DBServer = $ServerFriendlyName
DataCenter = $dataCenter
Connectivity = $False
}
}else
{
$connectivityResult =#{
DBServer = $ServerFriendlyName
DataCenter = $dataCenter
Connectivity = $True
}
}
$connectivityResult | ConvertTo-Json -Compress | Out-File -Encoding utf8 -LiteralPath ($DBCheckPath + "DBCheck.html")
}
##TODO: Only report Connectivity Serviceable= $false when there are two logs with $false value within 5 minutes.
}catch
{
$errorMessage = $_.Exception
## Only return $false if the exception was thrown because it can't connect for some reason. Otherwise
## throw the general exception
if ($errorMessage -match 'The server was not found' -or 'timeout')
{
$connectivityResult = #{
DBServer = $ServerFriendlyName
DataCenter = $dataCenter
Connectivity = $False
ErrorMessage = $errorMessage.GetBaseException().message
}
$connectivityResult | ConvertTo-Json | Out-File -Encoding utf8 -LiteralPath ($reportPath + $logTime + ".json")
$connectivityResult | ConvertTo-Json | Out-File -Encoding utf8 -LiteralPath ($DBCheckPath + "DBCheck.html")
}
}
finally
{
$sqlConnection.Close()
}
}

Add a computer to an AD group on a specific domain controller via ADSI adapter

I run this script in a user context that has privileges to add members to my AD group. I verified permissions already and I can add members manually via ADUC.
I'd like to add my machine to a specific group on a specific domain controller. I'm very unfamiliar with ADSI usage and I pieced together the below script based on other examples. I'm unable to use PS AD module at the time this script will be ran.
Param(
[Parameter(Mandatory)]
[string]$GroupName
)
#Find domain controllers
$searcher = New-Object System.DirectoryServices.DirectorySearcher([adsi] "LDAP://OU=Domain Controllers,DC=corp,DC=thing,DC=com")
$searcher.Filter = "(objectclass=computer)"
$DomainControllers = $searcher.FindAll()
Write-Verbose "Found DCs:"
foreach ($dc in $DomainControllers.Properties.cn)
{
Write-Verbose "$dc"
}
$TargetController = $null
$ComputerDn = $null
foreach ($dc in $DomainControllers.Properties.cn)
{
$searcher = New-Object System.DirectoryServices.DirectorySearcher([adsi] "LDAP://$dc/DC=corp,DC=thing,DC=com")
$searcher.Filter = "(&(objectclass=computer)(cn=$env:COMPUTERNAME))"
$result = $searcher.FindOne()
try {
if ($result)
{
$TargetController = $dc
Write-Verbose "Target controller set: $TargetController"
$ComputerDn = $result.Properties.distinguishedname
Write-Verbose "Computer DN: $ComputerDn"
break
}
else
{
Write-Verbose "Did not find $env:COMPUTERNAME on $dc"
}
}
catch
{
Write-Verbose "$dc ERROR"
}
}
if ($TargetController)
{
$GroupSearcher = New-Object System.DirectoryServices.DirectorySearcher([adsi] "LDAP://$TargetController/DC=corp,DC=thing,DC=com")
$GroupSearcher.Filter = "(&(objectclass=group)(cn=$GroupName))"
$GroupDn = $GroupSearcher.FindOne().Properties.distinguishedname
$Group = [ADSI] "LDAP://$TargetController/$GroupDn"
$ComputerSearcher = New-Object System.DirectoryServices.DirectorySearcher([adsi] "LDAP://$TargetController/DC=corp,DC=thing,DC=com")
$ComputerSearcher.Filter = "(&(objectclass=computer)(cn=$env:COMPUTERNAME))"
$result = $ComputerSearcher.FindOne().Properties.memberof -match "cn=$GroupName,"
if (!$result)
{
try
{
$Computer = [adsi] "LDAP://$TargetController/$ComputerDn"
$Group.Add("$Computer")
}
catch
{
$_.Exception.Message ; Exit 1
}
}
else
{
Write-Verbose "$env:COMPUTERNAME already a member of $GroupName"
}
}
Running this I get the error "Exception calling "Add" with "1" argument(s): "Exception from HRESULT: 0x80005000". I'm open to any alternatives!
As Bill Stewart commented you should either remove the [adsi] accelerator
$Computer = "LDAP://$TargetController/$ComputerDn"
$Group.Add($Computer)
or specify the path
$Computer = [adsi] "LDAP://$TargetController/$ComputerDn"
$Group.Add($Computer.path)
The method expects the path which you've already constructed with "LDAP://$TargetController/$ComputerDn" which makes the cast to an adsi object unnecessary.

using adsisearcher to find computer name in domain if exist or not and return a value to result = true

my script is trying to check if you entered a computer neme
$credObjects = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $userNames, $passwords
$Credential = Get-Credential -Credential $credObjects
$Searcher = New-Object -TypeName System.DirectoryServices.DirectorySearcher
$searcher = [adsisearcher]"(&(objectCategory=computer)(objectClass=computer)(name=$global:NewComputerName))"
$searcher.PropertiesToLoad.AddRange(('name'))
$searchResult = $searcher.FindAll()
if($searchResult.count -eq 1)
{
$Result = $true
}
else
{
$Result = $False
}
and them use it in if statement to popup message
elseif ($Result -match 'true')
{
$msgBoxInput7 = [System.Windows.Forms.MessageBox]::Show('computer is exist', 'OK')
switch ($msgBoxInput7) {
'OK' {
$groupbox1.ResumeLayout()
$form1.ResumeLayout()
$form1.add_FormClosed($Form_Cleanup_FormClosed)
}
}
}
any help to make it work
the code is working fine if i run script in admin in powershell
but when run it as user not working as expected

Problem with function calling function in PowerShell

I have two functions:
CreateComputer-Group
CreateCoomputer-Role
Once first function executes then GroupCreated in first function is used in second function to create computer role. How can I make sure first function execution is completed and then only second function to execute.
Here is the code:
$global:usergroup = "TACACS Admins"
$global:computerrole = "123413-NPARC"
$global:zone = "AWS"
$username = "<>"
$password = "<>"
[String[]] $global:HostServers = 'smp001-01','sl1ps01-13-8'
#[String[]] $global:HostServers = $hostServer.Replace("'","").Split(",")
Import-Module ActiveDirectory
Import-Module Centrify.DirectControl.PowerShell
$Password = ConvertTo-SecureString $password -AsPlainText -Force
$global:Cred = New-Object System.Management.Automation.PSCredential($username, $Password)
Set-CdmCredential -Domain test.com -Credential $Cred
function CreateComputer-Group {
Param($Cred,$zone,$computerrole)
try {
New-ADGroup -Path "ou=Role Groups-Computer,ou=Centrify,ou=Operations,dc=qateradatacloud,dc=com" -Name $computerrole -GroupScope Global -GroupCategory Security -Credential $Cred -ErrorAction Stop
} catch {
$ErrorMessage = $_.Exception
return $ErrorMessage
break
}
}
function create-computerRole {
try {
$ADGroupName = Get-ADGroup -Identity $computerrole
Write-Host "********** Get Command Outout *********"
Write-Host $ADGroupName
Write-Host $CustomerZone
Write-Host $computerrole
$global:Hellow = New-CdmComputerRole -Zone $CustomerZone -Name $computerrole -Group $ADGroupName
Write-Host $Hellow
} catch {
$ErrorMessage = $_.Exception
return $ErrorMessage
}
}
Not sure why New-CdmComputerRole command showing no such object on server.
Here is the output:
********** Get Command Outout *********
CN=123413-NPARC,OU=Role Groups-Computer,OU=Centrify,OU=Operations,DC=qateradatacloud,DC=com
CN=AWS,CN=qateradatacloud,CN=Zones,OU=Centrify,OU=Operations,DC=qateradatacloud,DC=com
123413-NPARC
System.DirectoryServices.DirectoryServicesCOMException (0x80072030): There is no such object on the server.
at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
at System.DirectoryServices.DirectoryEntry.Bind()
at System.DirectoryServices.DirectoryEntry.RefreshCache(String[] propertyNames)
at Centrify.DirectControl.Util.AD.DirectoryEntryEx.RefreshCache(DirectoryEntry de, String[] propertyNames)
at Centrify.DirectControl.Util.ActiveDirectory.Session.GetDirectoryEntryCheckOffline(String domainDcIpNetbios, String dn, String[] propertiesToLoad)
at Centrify.DirectControl.Util.ActiveDirectory.Session.GetDirectoryEntry(String domainDcIpNetbios, String dn, String[] propertiesToLoad)
at Centrify.DirectControl.Util.ActiveDirectory.Session.GetDirectoryEntry(String dn, String[] propertiesToLoad)
at Centrify.DirectControl.PowerShell.Types.CdmAdPrincipal.BindDirectoryEntry(Session session)
at Centrify.DirectControl.PowerShell.Types.CdmAdObject.Bind(Session session)
at Centrify.DirectControl.PowerShell.Commands.NewCdmComputerRole.InnerBeginProcessing()
at Centrify.DirectControl.PowerShell.CmdletBase.BeginProcessing()
at System.Management.Automation.Cmdlet.DoBeginProcessing()
at System.Management.Automation.CommandProcessorBase.DoBegin()
Finally I had split entire script into two scripts. One for Create AG-Group and another for all Centrify Commands

Moving computer to another OU in OSD with PowerShell

I am having a lot of trouble getting this code to work in a TS environment.
From a Windows environment, it works great. Just about any variation you will find with a google search of this code works fine in Windows. However in a Task Sequence these variations just produce different error messages for why the computer can't be moved.
Unspecified Error
The specified domain either doesn't exist or couldn't be contacted
Instance of an object not set to an object
I feel that something is happening when we get to the psbase.MoveTo() method call. Up to that point, it can print something out that looks like a reasonable object. In other words, they aren't null or something.
Then psbase.MoveTo() says no.
Example code.
$logFile = "MoveComputerLog.txt"
# Domain Credentials
$account = "domain\osdaccount"
$password = "thepassword"
function logMessage {
param ([string]$logstring)
Write-Host $logstring
Add-content $logFile -value $logstring
}
$computerName = "COMPUTERNAME"
logMessage "computerName: $computerName"
$root = "LDAP://sweet.domain.com"
$domain = New-Object System.DirectoryServices.DirectoryEntry($root, $account, $password)
$search = New-Object System.DirectoryServices.DirectorySearcher($domain)
$search.filter = "(&(objectClass=computer)(name=$computerName))"
$result = $search.findall()
$computerDN = $result.Properties.Item("DistinguishedName")
logMessage "DN: $computerDn"
$computer = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$computerDN", $account, $password)
logMessage "Computer: $computer"
$destination = "LDAP://ou=here,ou=goes,ou=it,dc=sweet,dc=domain,dc=com"
$ou = New-Object System.DirectoryServices.DirectoryEntry($destination, $account, $password)
try {
# "The specified domain couldn't be connected or doesn't exist."
$computer.psbase.MoveTo($ou.Path)
} catch {
Write-Host "Encountered error while moving $computerName"
logMessage $error[0]
}
Here is the definition, ADSI is important:
PS C:\> $computer.psbase.MoveTo
OverloadDefinitions
-------------------
void MoveTo(adsi newParent)
void MoveTo(adsi newParent, string newName)
You can try this, rigth after $result = $search.findall() :
$computer = [ADSI]$result.path
$computer.psbase.Moveto( [ADSI]LDAP://ou=here,ou=goes,ou=it,dc=sweet,dc=domain,dc=com )