Need help expanding searchbase variable

Hello all,

I am not very experienced with PowerShell. I am working on something that when I put it in a write-host, it seems to work OK. When I then put it into my main script, it fails. Note, if I manually expand out the searchbase, instead of using the variable, the script works OK. I’m setting up a ‘template’ script that others at my company could use for multiple domains, without needing to change the script at all. The searchbase variable however does not seem to be expanding, so the command fails. I’ve tried {}, (), and “”. Help!

$strOU = "Computers"
$strDomain = (Get-ADDomain -Current LocalComputer)
$searchb = "OU="+"$strOU"+","+"$strDomain"
if(Get-ADComputer -Filter {OperatingSystem -Like "*Windows*"} -SearchBase "$searchb" -properties * |Select-Object name,OperatingSystem)
	{
		Get-ADComputer -Filter {OperatingSystem -Like "*Windows*"} -SearchBase ("$searchb") -properties * |Select-Object name,OperatingSystem | Export-csv C:\UnsortedWorkstations.csv -notypeinformation -encoding utf8
	} else {
		exit
	}

I avoid Write-Host religiously ;).

First, I would avoid concatenating strings. There’s no need. See https://devopscollective.gitbooks.io/the-big-book-of-powershell-gotchas/content/manuscript/dontconcatenatestrings.html.

$searchb = "OU=$strOU,$strDomain"

That should work fine. Additionally, there’s no need for -SearchBase “$searchb”, just use -SearchBase $searchb.

The problem you’re doubtless running into is that you expect $strDomain to contain a domain name as a string. It does not. It contains a domain object, with many properties. You probably meant to…

$strDomain = Get-ADDomain -Current LocalComputer | Select-Object -Expand Name

Assuming the Name property is what you want. See https://devopscollective.gitbooks.io/the-big-book-of-powershell-gotchas/content/manuscript/properties-vs-values.html. Likely, the problem wasn’t with your $searchb variable, but rather your $strDomain variable. I suspect if you ran that $strDomain line at the console, and then looked at the result, it wouldn’t be what you wanted without the Select -Expand.

And, as a completely unrelated note, most PowerShell folks don’t use the old VBScript-style “str” variable naming. Totally up to you, though.

I’ll also selfishly recommend Learn Windows PowerShell in a Month of Lunches as a good way to not get clobbered by that stuff, and Learn PowerShell Toolmaking in a Month of Lunches as a way to not go down the wrong path in writing these tools for other people to use ;).

And I’ll go you one better with showing you how I’d have debugged this (from Toolmaking):

$VerbosePreference = 'Continue'

$strOU = "Computers"
$strDomain = (Get-ADDomain -Current LocalComputer)
$searchb = "OU="+"$strOU"+","+"$strDomain"
Write-Verbose "strOU is $strOU"
Write-Verbose "strDomain is $strDomain"
Write-Verbose "searchb is $searchb"

if(Get-ADComputer -Filter {OperatingSystem -Like "*Windows*"} -SearchBase "$searchb" -properties * |Select-Object name,OperatingSystem)
	{
		Get-ADComputer -Filter {OperatingSystem -Like "*Windows*"} -SearchBase ("$searchb") -properties * |Select-Object name,OperatingSystem | Export-csv C:\UnsortedWorkstations.csv -notypeinformation -encoding utf8
	} else {
		exit
	}

That way you can confirm that your variables contain what you expected them to. 99.2% of bugs are from a variable containing something other than what you thought it did. The first step is always to confirm from inside the script, not using Write-Host (which is an entirely different creature).

Thanks, Don! I haven’t had a chance to dig back into this today, but you’ve given me a great amount to look over.

The concept of the script, is to be able to have any tech run this at a client, regardless of the domain, and without editing the script. The script will check the default Computers OU, and IF there are ANY objects in there “like Windows…” then it will write a text file containing the names of those objects. If there are not, it will then exit.

In the long run, I’ll be tying in an RMM tool to monitor for that text file… =)

Thanks,
Michael

Don,

That’s been a huge help so far - thank you! I was able to track down that it’s “DistinguishedName” that I need to expand. Here is what I have now, and below that is the error I’m getting.

$VerbosePreference = 'Continue'
$strOU = "Computers"
$strDomain = (Get-ADDomain -Current LocalComputer | Select-Object -Expand DistinguishedName)
$searchb = "OU=$strOU,$strDomain"
Write-Verbose "strOU is $strOU"
Write-Verbose "strDomain is $strDomain"
Write-Verbose "searchb is $searchb"
if(Get-ADComputer -Filter {OperatingSystem -Like "*Windows*"} -SearchBase $searchb -properties * |Select-Object name,OperatingSystem)
	{
		Get-ADComputer -Filter {OperatingSystem -Like "*Windows*"} -SearchBase ("$searchb") -properties * |Select-Object name,OperatingSystem | Export-csv C:\UnsortedWorkstations.csv -notypeinformation -encoding utf8
	} else {
		exit
	}

The error is:

VERBOSE: strOU is Computers
VERBOSE: strDomain is DC=achsd,DC=org
VERBOSE: searchb is OU=Computers,DC=achsd,DC=org
Get-ADComputer : Directory object not found
At C:\Users\innovation\Desktop\ComputersOUCheck.ps1:8 char:4
+ if(Get-ADComputer -Filter {OperatingSystem -Like "*Windows*"} -SearchBase $searc ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (:) [Get-ADComputer], ADIdentityNotFoun 
   dException
    + FullyQualifiedErrorId : Directory object not found,Microsoft.ActiveDirectory.Ma 
   nagement.Commands.GetADComputer

The if statement does work - when I manually type out the searchbase, rather than using the variable, which is why I was thinking it has to be something related to that which I’m doing wrong.

That’s an Active Directory question ;). “Computers” isn’t an OU. It’s a container = so it’s named with CN.

You Sir, are a hero. Thank you! Can’t believe I missed that. Always the simple things, eh?