Share via


Get-ADUser -SearchBase 'variable' - filter won't work

Question

Thursday, July 16, 2020 3:11 PM

Hi folks, thanks in advance. 

I can't get Get-ADUser -SearchBase to work with a variable even though the variable contains the exact same Path (ou=sublocation,ou=location,ou=Organisation,DC=Organisation,DC=net) in AD as if the path was hard coded into to the script (which works like a charm). 

Here is the full code for this portion. 

    

Get-ADUser -SearchBase $fullNewPath -Filter {((Enabled -eq $true) -and 

    (LastLogonDate -lt $time))} -Properties LastLogonDate | 

    select samaccountname, Name, LastLogonDate | Sort-Object LastLogonDate | 

    Export-Csv -path $location -Force -notypeinformation

All replies (18)

Thursday, July 16, 2020 3:17 PM

Oh, just to say the function that converts a copied path for AD (which is in the wrong format) to a string in the correct path works perfectly and ends up in the following variable

> $fullNewPath 

"ou=sublocation,ou=location,ou=Organisation,DC=Organisation,DC=net"


Thursday, July 16, 2020 3:59 PM

could you provide exact error message?

The opinion expressed by me is not an official position of Microsoft


Thursday, July 16, 2020 6:40 PM

I don't think there's any reason why that would present a problem. However, just for the sake of clarity, are you saying you're translating a name ("a copied path for AD") from a canonical name (ADSPath) to a distinguished name (DN)?

In other words, from the form "Organization.net/Organization/location/sublocation".

If you use the same canonical name, and the same function to convert it to a distinguished name, can you use the result in a Get-OrganizationalUnit cmdlet successfully?

Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)


Friday, July 17, 2020 1:34 PM

I've changed the name of our domain to Organisation below. Cheers for the reply. 

Get-ADUser : The supplied distinguishedName must belong to one of the following partition(s): 'DC=Organisation,DC=net , CN=Configuration,DC=Organisation,DC=net , 
CN=Schema,CN=Configuration,DC=Organisation,DC=net , DC=DomainDnsZones,DC=Organisation,DC=net , DC=ForestDnsZones,DC=Organisation,DC=net'.
At D:\DataFromOldPCDrive\DisableADAccounts\DisableADUserAccounts.ps1:108 char:5
+     Get-ADUser -SearchBase $fullNewPath -Filter {((Enabled -eq $true) -and
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Get-ADUser], ArgumentException
    + FullyQualifiedErrorId : The supplied distinguishedName must belong to one of the following partition(s): 'DC=Organisation,DC=net , CN=Configuration,DC=Organisation,DC=net 
    , CN=Schema,CN=Configuration,DC=Organisation,DC=net , DC=DomainDnsZones,DC=Organisation,DC=net , DC=ForestDnsZones,DC=Organisation,DC=net'.,Microsoft.ActiveDirectory.Mana  
  gement.Commands.GetADUser

import-csv : Could not find file 'D:\DataFromOldPCDrive\DisableADAccounts\UsersToDisable 17072020 143015.csv'.
At D:\DataFromOldPCDrive\DisableADAccounts\DisableADUserAccounts.ps1:127 char:5
+     import-csv $location | foreach-object {
+     ~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OpenError: (:) [Import-Csv], FileNotFoundException
    + FullyQualifiedErrorId : FileOpenFailure,Microsoft.PowerShell.Commands.ImportCsvCommand

 


Friday, July 17, 2020 1:42 PM

Hi its being copied as Organisation.net/Organisation/Location/Sublocation from the     Properties Object of the OU and pasted in as the scripts asks for a path. The script then changes it to whats below, the correct format. 

to "ou=sublocation,ou=location,ou=Organisation,DC=Organisation,DC=net"

This means if you have someone is running the script they can't really mess up too much. Plus is me trying to cover all angles. 

Thanks again. 


Friday, July 17, 2020 1:43 PM

I've changed the name of our domain to Organisation below. Cheers for the reply. 

Get-ADUser : The supplied distinguishedName must belong to one of the following partition(s): '**DC=Organisation,DC=net , CN=Configuration,DC=Organisation,DC=net , **
CN=Schema,CN=Configuration,DC=Organisation,DC=net , DC=DomainDnsZones,DC=Organisation,DC=net , DC=ForestDnsZones,DC=Organisation,DC=net'.
At D:\DataFromOldPCDrive\DisableADAccounts\DisableADUserAccounts.ps1:108 char:5
+     Get-ADUser -SearchBase $fullNewPath -Filter {((Enabled -eq $true) -and
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Get-ADUser], ArgumentException
    + FullyQualifiedErrorId : The supplied distinguishedName must belong to one of the following partition(s): 'DC=Organisation,DC=net , CN=Configuration,DC=Organisation,DC=net 
    , CN=Schema,CN=Configuration,DC=Organisation,DC=net , DC=DomainDnsZones,DC=Organisation,DC=net , DC=ForestDnsZones,DC=Organisation,DC=net'.,Microsoft.ActiveDirectory.Mana  
  gement.Commands.GetADUser

import-csv : Could not find file'D:\DataFromOldPCDrive\DisableADAccounts\UsersToDisable 17072020 143015.csv'.
At D:\DataFromOldPCDrive\DisableADAccounts\DisableADUserAccounts.ps1:127 char:5
+     import-csv $location | foreach-object {
+     ~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OpenError: (:) [Import-Csv], FileNotFoundException
    + FullyQualifiedErrorId : FileOpenFailure,Microsoft.PowerShell.Commands.ImportCsvCommand

ok, so you have broken distinguishedname in your variable

code related to the second error not provided but my guess that thamting not ok with the path. you can try import-csv "$location"

The opinion expressed by me is not an official position of Microsoft


Friday, July 17, 2020 1:45 PM

why just not provide dn in correct format? You can simply copy DN from OU Properties from ADUC

looks like more problems was implemented that solved.

please provide full code, if you have any issues that you want to discuss

The opinion expressed by me is not an official position of Microsoft


Friday, July 17, 2020 3:32 PM

That's just repeating what you already said.

Let's see the code that does the translation from canonical name to distinguished name, and an unaltered view of both the input and the result.

Looking at the error message, are you absolutely sure that there isn't a trailing space at the end of "...,DC=net" when the DN is returned from your conversion?

If you've written your own conversion routine, try using on from here and see of the result is the same.

https://gist.github.com/joegasper/3fafa5750261d96d5e6edf112414ae18

Or, using the ADSI NameTranslate interface. Here's an example of how to do that:

Function NameTranslator{
    param(
        [string]$name
    )    

    #Name Translator Initialization Types
    $ADS_NAME_INITTYPE_DOMAIN   = 1
    $ADS_NAME_INITTYPE_SERVER   = 2
    $ADS_NAME_INITTYPE_GC       = 3
    #Name Transator Name Types
    $DISTINGUISHEDNAME     = 1
    $CANONICALNAME         = 2
    $NT4NAME               = 3
    $DISPLAYNAME           = 4
    $DOMAINSIMPLE          = 5
    $ENTERPRISESIMPLE      = 6
    $GUID                  = 7
    $UNKNOWN               = 8
    $USERPRINCIPALNAME     = 9
    $CANONICALEX          = 10
    $SERVICEPRINCIPALNAME = 11
    $SIDORSIDHISTORY      = 12

    $ns=New-Object -ComObject NameTranslate
    [System.__ComObject].InvokeMember("init","InvokeMethod",$null,$ns,($ADS_NAME_INITTYPE_GC,$null))
    [System.__ComObject].InvokeMember("Set","InvokeMethod",$null,$ns,($UNKNOWN,$name))
    [PSCustomObject]@{
        DN = [System.__ComObject].InvokeMember("Get","InvokeMethod",$null,$ns,$DISTINGUISHEDNAME)
        Canonical = [System.__ComObject].InvokeMember("Get","InvokeMethod",$null,$ns,$CANONICALNAME)
        Display = [System.__ComObject].InvokeMember("Get","InvokeMethod",$null,$ns,$DISPLAYNAME)
    }
}


NameTranslator "Organization.net/Organization/location/sublocation"

Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)


Monday, July 20, 2020 8:07 AM

Import-module activedirectory

clear-Host

    $domain = "Organisation.net" 
    $currentDate = Get-Date 
    $datetimeToString = $currentDate.ToString()

#********************************************************************************************************************************************************************

# This next block of two variables, and a Do Until Loop captures how many days 
# from the user they want to use to check for inactive accounts.  

    $DaysInactive = 0
    $inputOK = $false

do
{
    try 
    {
        $DaysInactive = Read-Host "Please enter a whole number between 1 and 731"
        if(([int]$DaysInactive) -and (1..731 -contains $DaysInactive)) {
        $inputOK = $true
        } 
    }

catch 

    {
        write-Host -ForegroundColor red "Your Input is completely the wrong type, Please enter a whole number between 1 and 731 !!!"
    }

}
until ($inputOK) 

# ********************************************************************END LOOP*****************************************************************************************

# This line gets sets the cut off date for disabling stale user accounts in AD.

    $time = (Get-Date).Adddays(-($DaysInactive))

# This line, gets the file name to export as a .csv file further down the program. 
        
    $filename = 'UsersToDisable' + " " + $datetimeToString + '.csv'

# This line cleans up the file name so we can save it. Followed by creating the fullpath for the file. 

    $filename = $filename -replace '[/:]'
    $location = (Get-Location).ToString() + '\ + $filename 
 

# ***********************************************************This whole block of code asks the user for the specific OU path.**********************************************  

$counter = 0

$list = New-Object System.Collections.ArrayList
$newPath = ""

Write-Host # Writes a blank line, to make the output tidy.

$ouPath = Read-Host "Please enter target Active Directory Organisational Unit path"

do {

       if ($ouPath -ne "Organisation.net/Organisation"){
    
          $ouPath = $ouPath -replace "Organisation.net/Organisation" -replace ""

          $ouLength = $ouPath.Length
    
          $ouFSIndex = $ouPath.LastIndexOf("/", $ouLength -1)

          $section = $ouPath.SubString( $ouFSIndex )

          $list.add(("$section")) > $null 
 
          $newPath = $newPath + $list[$counter] + ","
          
          $counter ++ 
                            
          $ouPath = $ouPath -replace $section -replace ""   
                    
          } else {
            
            # This is space is just here to make this function work. 
            
          }

    } While ($ouFSIndex -gt 0)

   write-host
   $newPath = $newPath + "/Organisation,DC=Organisation,DC=net"
   $fullNewPath = '"'
   $fullNewPath = $fullNewPath + $newPath.Replace("/", "ou=")
   $fullNewpath = $fullNewPath + '"'
   write-output $fullNewPath

# ***********************************************************END BLOCK**********************************************

# Get all AD Users with lastLogonTimestamp less than our time.

    Get-ADUser -SearchBase $fullNewPath -Filter {((Enabled -eq $true) -and 
                 
    (LastLogonDate -lt $time))} -Properties LastLogonDate | 
 
# Output hostname, name and lastLogonTimestamp into CSV

    select samaccountname, Name, LastLogonDate | Sort-Object LastLogonDate | 

# Export the .csv file in the information, that will be used in the next section. 

    Export-Csv -path $location -Force -notypeinformation
    

# *********************************************************************************************************

# This line imports a .csv file, with a list of user accounts by SAM Account Name to be disabled.

    import-csv $location | foreach-object { 

# This line creates a variable to hold each SAM Account name as 
# it rotates through the For Each loop sequentially. 
    
    $samAccountName = $_."samAccountName" 

# This is the line that disables the SAM Account in AD. 

    Set-ADUser -Identity $samAccountName -Enabled $false 

# This line moves the now disabled SAM Account, into the disabled OU. 

    Get-ADUser $samAccountName | Move-ADObject –TargetPath "OU=DisabledObjects,DC=Organistion,DC=net"    
}


Monday, July 20, 2020 12:07 PM

hi mokee03, is this is a part of question, or it's your solution?

please use codeblocks for next code posting, in this way your code will be more readeble

The opinion expressed by me is not an official position of Microsoft


Monday, July 20, 2020 2:03 PM

That's the whole code of the script I have created. It's all working only the bit where the path has to be hard coded in to work. I trying to avoid hard coding paths in to the code, that way its more interactive with the users. The following variable $fullNewPath should be used instead of hard coding the path in. 

I'm not a programmer by trade, I work in support, so my apologizes for imperfectly written code etc. 


Monday, July 20, 2020 4:56 PM

That's the whole code of the script I have created. It's all working only the bit where the path has to be hard coded in to work. I trying to avoid hard coding paths in to the code, that way its more interactive with the users. The following variable $fullNewPath should be used instead of hard coding the path in. 

I'm not a programmer by trade, I work in support, so my apologizes for imperfectly written code etc. 

you can use this button even if you are not a technician

with using this magick button your code would looks like a code but not a long read plain text

The opinion expressed by me is not an official position of Microsoft


Monday, July 20, 2020 6:22 PM | 2 votes

Don't add quotation marks! The quotation marks are now part of the value stored in the variable and there's no OU named '"ou=sublocation,ou=location,ou=Organisation,DC=Organisation,DC=net"'

   $newPath = $newPath + "/Organisation,DC=Organisation,DC=net"
#  $fullNewPath = '"'                                           <=== NO
   $fullNewPath = $fullNewPath + $newPath.Replace("/", "ou=")
#  $fullNewpath = $fullNewPath + '"'                            <=== NO
   write-output $fullNewPath

Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)


Tuesday, July 21, 2020 8:18 AM

Ok cool. Thanks for that tool. 


Tuesday, July 21, 2020 8:19 AM

Hi, I will try this today and get back to you with the result. Fingers, toes crossed. :-)


Tuesday, July 21, 2020 9:53 AM

Rich, that worked perfectly, the only thing else I had to do was initiate $fullNewPath back to "" as Powershell doesn't clear variable memory spaces after the program is finished. Powershell also appears to use the same space in memory as the previous instance of the program. 

Again a big thank you for that and all participants. 

Michael. 


Tuesday, July 21, 2020 6:06 PM

Rich, that worked perfectly, the only thing else I had to do was initiate $fullNewPath back to "" as Powershell doesn't clear variable memory spaces after the program is finished. Powershell also appears to use the same space in memory as the previous instance of the program. 

Again a big thank you for that and all participants. 

Michael. 

All variables are always removed when any process ends.  There is never a need to clear them.  This is a simple beginning computers 101 issue.

\(ツ)_/


Tuesday, July 21, 2020 6:39 PM | 1 vote

PowerShell doesn't retain those variables . . . the ISE does though. Run your script from a .ps1 file in the PowerShell console and that problem will go away.

Another, and probably better, thing to do is to stop using the ISE and switch to VS Code for your development.

Rich Matheisen MCSE&I, Exchange Ex-MVP (16 years)