I’m in the process of writing a new tool. It’s basically a wrapper function for Get-ADObject that only returns Active Directory (AD) contact objects. While there’s a Get-ADComputer cmdlet to get AD computer objects, and a Get-ADUser cmdlet to get AD user objects, there’s no specific cmdlet for contacts. There’s no surprise here really, and that’s likely why we have a Get-ADObject cmdlet. It’s for those AD objects that didn’t make the cut and get their own.
I’ve seen some discussion on this in the past: How do I handle running a cmdlet within a function when I don’t know if a parameter and parameter value will be included, or not? Let’s consider that my Get-ADContact function will run the Get-ADObject cmdlet, as seen below. In the Begin block, we create a $Parameter variable that will hold a hash table. We’ll populate it in such a way that the key Filter will have a corresponding value of {ObjectClass -eq ‘contact’}. In the Process block, we splat this hash table, currently with a single parameter and parameter value, to the Get-ADObject cmdlet.
Function Get-ADContact { [CmdletBinding()] Param ( ) Begin { # Create parameter hash table; add Filter parameter. $Parameters = @{Filter = {ObjectClass -eq 'contact'}} } # End Begin. Process { Get-ADObject @Parameters } # End Process. End { } # End End. } # End Function: Get-ADContact.
There’s two other parameters included in Get-ADObject that I want to allow my users the ability to include. That’s the -SearchBase and -SearchScope parameters. You can read more by checking the help for Get-ADObject: Get-Help -Name Get-ADObject. There’s actually several AD cmdlets that also include these parameters. They can be quite helpful, so that’s why I’ve decided to include them.
Before we continue, I want to let the audience know that I am familiar with creating proxy functions, and I understand it might’ve been a better option. Maybe I’ll circle back sometime and see about replicating the functionality I’ve created here, in that manner. It might turn out this wasn’t worth writing and posting. No guarantee, but it’s possible.
Okay, back on track. Let’s add the additional lines inside the Param block, that make accepting a -SearchBase and -SearchScope parameter value possible.
Function Get-ADContact { [CmdletBinding()] Param ( [Parameter()] [string]$SearchBase, [Parameter()] [ValidateSet(0,'Base',1,'OneLevel',2,'SubTree')] $SearchScope ) Begin { # Create parameter hash table; add Filter parameter. $Parameters = @{Filter = {ObjectClass -eq 'contact'}} } # End Begin. Process { Get-ADObject @Parameters } # End Process. End { } # End End. } # End Function: Get-ADContact.
Now, our Get-ADContact function will include the two additional parameters. Neither parameter is mandatory, but the -SearchScope parameter does include a ValidateSet parameter attribute to ensure it’ll only accept the values 0, 1, 2, Base, OneLevel, or SubTree. Base and 0 are equivalent, as are 1 and OneLevel, and 2 and SubTree.
The next thing I need to do is include the parameter values assigned to the -SearchBase and -SearchScope parameters to our $Parameters hash table when those are included. I decided to do this using the $PSBoundParameters variable, the ForEach-Object cmdlet, and the switch language construct.
Function Get-ADContact { [CmdletBinding()] Param ( [Parameter()] [string]$SearchBase, [Parameter()] [ValidateSet(0,'Base',1,'OneLevel',2,'SubTree')] $SearchScope ) Begin { # Create parameter hash table; add Filter parameter. $Parameters = @{Filter = {ObjectClass -eq 'contact'}} $PSBoundParameters.Keys | ForEach-Object { Switch ($_) { 'SearchBase' {$Parameters += @{SearchBase = $SearchBase}; break} 'SearchScope' {$Parameters += @{SearchScope = $SearchScope}} } } } # End Begin. Process { Get-ADObject @Parameters } # End Process. End { } # End End. } # End Function: Get-ADContact.
All done. Now, we have function that only returns AD contact objects. Additionally, we have the option of narrowing down our search by including the often used -SearchBase and -SearchScope parameters. While I don’t doubt there’s a better way, I think this one will work for now.