Author Posts

May 6, 2014 at 6:32 pm

Alright so I am breaking down...I need your help figuring out the logic I need to write for this function to work.

What this function does (or what it is supposed to do):
Look through our AD environment based on parameters specified after the search-AD_object cmdlet is passed. Mostly searching through OU's and finding users and large amount of computers in different office locations.

What I am trying to accomplish:
As you can see there are four parameters, and the function worked great with the first three parameters until I added the fourth $type parameter today and messed with all of my logic. So I want the user running the function to have the option to search through an OU,possible sub OU and pull out only the objects in the OU matching the type (i.e. computer,user,group). As you can see I currently have a bunch of elseif statements (which I actually dont like and I find them to be alot of clutter but I am still learning powershell and its what I have for now).

What currently happens:

Say I run my new command with the given parameters

"Search-AD_Object -OrganizationalUnit Campus_San_Marcos -Type Computer"

in a way it works but it gives me every type of object in the OU, which is a no because I only want the computers.

Where I am at now:

currently frustrated at my lack of logic skills. So if you have any guidance to resolve my issue that would be great, even if you think you can add efficiency to my code, I would love to hear it.

$OrganizationalUnit
$SubOrganizationalUnit
$ObjectName
$Type


function Search-AD_Object
{
[CmdletBinding()]

Param(
[Parameter (Mandatory=$true)]
[ValidateSet('_Servers','Application_Accounts','Builtin','Campus_Austin','Campus_Co-Lo','Campus_FLEX','Campus_Online','Campus_Saint_Augustine','Campus_San_Marcos','Computers','Domain Controllers','Exchange Groups','Exchange Mailboxes','External Contacts','ForeignSecurityPrincipals','Groups','IT Personnel','Laureate','LostAndFound','Managed Service Accounts','Microsoft Exchange Security Groups', 'Students','Students_i nactive','Users')]

[string]$OrganizationalUnit,

[ValidateSet('_Servers','_Dev_Servers','Faculty','Library','Finance','Smart_Carts','Staff','Computers','Users')]
[string]$SubOrganizationalUnit,

[string[]]$ObjectName,

[ValidateSet('Computer','User','Group','site')]
[string]$Type,

)

BEGIN{

$ou_result = Get-ADObject -LDAPFilter "(name=*)" -SearchBase "DC=xxx,DC=xxx" -SearchScope OneLevel | `
Where-Object {$_.Name -eq "$OrganizationalUnit"} | `
Select DistinguishedName -ExpandProperty DistinguishedName

Write-Host "-----------------------------------------------------------"
Write-Host "You're Searching in the $ou_result OU" -ForegroundColor Green
Write-Host "-----------------------------------------------------------"
r
$sub_result = Get-ADObject -LDAPFilter "(name=*)" -SearchBase $ou_result -SearchScope OneLevel | `
Where-Object {$_.Name -eq "$SubOrganizationalUnit"} | `
Select DistinguishedName -ExpandProperty DistinguishedName

If(-not($SubOrganizationalUnit) -and ($Type)) {
$Search = Get-ADObject -LDAPFilter "(name=*)" -SearchBase $ou_result | `
Where-Object {$_.Name -match "$ObjectName"} | `
Select Name

echo $Search
}
elseif($SubOrganizationalUnit) {
Write-Host "-----------------------------------------------------------"
Write-Host "You're now in $sub_result OU" -ForegroundColor Green
Write-Host "-----------------------------------------------------------"

$Search = Get-ADObject -LDAPFilter "(name=*)" -SearchBase $sub_result -SearchScope OneLevel | `
Where-Object {$_.Name -match "$ObjectName"} | `
Select Name -ExpandProperty Name

echo $Search
}

elseif($Type) {

$Search = Get-ADObject -LDAPFilter "(objectClass=$Type)" -SearchBase $ou_result -SearchScope Base | `
Where-Object {$_.Name -match "$ObjectName"} | `
Select Name -ExpandProperty Name

echo $Search
}

elseif($SubOrganizationalUnit -and $Type) {
Write-Host "-----------------------------------------------------------"
Write-Host "You're now in $sub_result OU" -ForegroundColor Green
Write-Host "-----------------------------------------------------------"

$Search = Get-ADObject -LDAPFilter "(objectClass=$Type)" -SearchBase $sub_result -SearchScope Base | `
Where-Object {$_.Name -match "$ObjectName"} | `
Select Name -ExpandProperty Name

echo $Search

}

}

PROCESS {

foreach ($i in $Search) {

Write-Host "this works"

}

}

}

May 7, 2014 at 7:49 am

Your function looks like a good effort, but there are a number of things wrong with it and a number of best practices that aren't being followed. There's no reason to use BEGIN/PROCESS since you're not accepting pipeline input on any of the parameters. There's also no need to use the line continuation character (backtick or grave accent) at the end of a line that ends in the pipe symbol since the pipe is a natural line break. In general, try to stay away from Write-Host and use Write-Verbose instead. I rarely if ever use LDAP filters (the LDAPFilter parameter), use the filter parameter instead since it's much easier to work with unless you have a specific reason for using LDAP filters. Remember to filter early (filter left) instead of filtering with the Where-Object cmdlet if at all possible (design for efficiency).

Here's what I came up with, without spending too much time on it. I would recommended adding comment based help and error handling along with thoroughly testing it before saying it's complete.


function Search-AD_Object {

    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$true)]
        [ValidateSet('_Servers',
                     'Application_Accounts',
                     'Builtin',
                     'Campus_Austin',
                     'Campus_Co-Lo',
                     'Campus_FLEX',
                     'Campus_Online',
                     'Campus_Saint_Augustine',
                     'Campus_San_Marcos',
                     'Computers',
                     'Domain Controllers',
                     'Exchange Groups',
                     'Exchange Mailboxes',
                     'External Contacts',
                     'ForeignSecurityPrincipals',
                     'Groups',
                     'IT Personnel',
                     'Laureate',
                     'LostAndFound',
                     'Managed Service Accounts',
                     'Microsoft Exchange Security Groups',
                     'Students',
                     'Students_inactive',
                     'Users',
                     'Test')]
        [string]$OrganizationalUnit,

        [ValidateSet('_Servers',
                     '_Dev_Servers',
                     'Faculty',
                     'Library',
                     'Finance',
                     'Smart_Carts',
                     'Staff',
                     'Computers',
                     'Users',
                     'Groups')]
        [string]$SubOrganizationalUnit,

        [ValidateNotNullorEmpty()]
        [string]$ObjectName = '*',

        [ValidateSet('Computer',
                     'User',
                     'Group',
                     'site',
                     '*')]
        [string]$Type = '*'
    )

    $OUSearchBase = Get-ADObject -Filter {Name -eq $OrganizationalUnit} -SearchBase "DC=mikefrobbins,DC=com" -SearchScope OneLevel |
                    Select-Object -ExpandProperty DistinguishedName

    If ($PSBoundParameters['SubOrganizationalUnit']) {
        
        $OUSearchBase = Get-ADObject -Filter {Name -eq $SubOrganizationalUnit} -SearchBase $OUSearchBase -SearchScope OneLevel |
                        Select-Object -ExpandProperty DistinguishedName
    }

    Write-Verbose -Message "You're Searching in the $OUSearchBase OU"

    $Search = Get-ADObject -Filter {Name -like $ObjectName -and ObjectClass -like $Type} -SearchBase $OUSearchBase |
              Select-Object -Property Name

    foreach ($s in $Search) {

        Write-Output "Current item is: $(($s).Name)"

    }
    
}