2014/04/05

PowerShell - Get a list of my domain Organizational Units

Quick post, last week my coworker Andrey needed to list all the Organization Units in the domain by Canonical Name. I thought sharing the PowerShell One-Liner magic could save time to some people out there.

In the following examples two methods to retrieve the information using Active Directory and ADSI/NET.



Active Directory Module

I found two ways to get this information using this module
  • Get-ADOrganizationUnit
  • Get-ADObject

First we need to verify if the module is loaded and then search for Cmdlet that could meet our needs.
# Check if the ActiveDirectory module is Loaded
Get-Module -Name ActiveDirevtory

# Check if the ActiveDirectory module is available
Get-Module -Name ActiveDirectory -ListAvailable

# Import the ActiveDirectory module
Import-Module -Name ActiveDirectory

# Find Cmdlets in the ActiveDirectory related to OrganizationalUnit
Get-Command -Module ActiveDirectory -Name *OrganizationalUnit*






Get-ADOrganizationalUnit

The Get-ADOrganizational unit cmdlet gets an organizational unit object or performs a search to retrieve multiple organizational units.

Straight forward, we look for the properties available to us.

# Get the properties available for each OrganizationalUnit object
Get-ADOrganizationalUnit -Filter * -Properties *| Get-Member


Output:
   TypeName: Microsoft.ActiveDirectory.Management.ADOrganizationalUnit

Name                            MemberType            Definition
----                            ----------            ----------
Contains                        Method                bool Contains(string propertyName)
Equals                          Method                bool Equals(System.Object obj)
GetEnumerator                   Method                System.Collections.IDictionaryEnumerator G...
GetHashCode                     Method                int GetHashCode()
GetType                         Method                type GetType()
ToString                        Method                string ToString()
Item                            ParameterizedProperty Microsoft.ActiveDirectory.Management.ADPro...
CanonicalName                   Property              System.String CanonicalName {get;}
City                            Property              System.String City {get;set;}
CN                              Property              System.String CN {get;}
Country                         Property              System.String Country {get;set;}
Created                         Property              System.DateTime Created {get;}
createTimeStamp                 Property              System.DateTime createTimeStamp {get;}
Deleted                         Property              System.Boolean Deleted {get;}
Description                     Property              System.String Description {get;set;}
DisplayName                     Property              System.String DisplayName {get;set;}
DistinguishedName               Property              System.String DistinguishedName {get;set;}
dSCorePropagationData           Property              Microsoft.ActiveDirectory.Management.ADPro...
gPLink                          Property              System.String gPLink {get;set;}
instanceType                    Property              System.Int32 instanceType {get;}
isCriticalSystemObject          Property              System.Boolean isCriticalSystemObject {get...
isDeleted                       Property              System.Boolean isDeleted {get;}
LastKnownParent                 Property              System.String LastKnownParent {get;}
LinkedGroupPolicyObjects        Property              Microsoft.ActiveDirectory.Management.ADPro...
ManagedBy                       Property              System.String ManagedBy {get;set;}
Modified                        Property              System.DateTime Modified {get;}
modifyTimeStamp                 Property              System.DateTime modifyTimeStamp {get;}
Name                            Property              System.String Name {get;}
nTSecurityDescriptor            Property              System.DirectoryServices.ActiveDirectorySe...
ObjectCategory                  Property              System.String ObjectCategory {get;}
ObjectClass                     Property              System.String ObjectClass {get;set;}
ObjectGUID                      Property              System.Nullable`1[[System.Guid, mscorlib, ...
ou                              Property              Microsoft.ActiveDirectory.Management.ADPro...
PostalCode                      Property              System.String PostalCode {get;set;}
ProtectedFromAccidentalDeletion Property              System.Boolean ProtectedFromAccidentalDele...
sDRightsEffective               Property              System.Int32 sDRightsEffective {get;}
showInAdvancedViewOnly          Property              System.Boolean showInAdvancedViewOnly {get...
State                           Property              System.String State {get;set;}
StreetAddress                   Property              System.String StreetAddress {get;set;}
systemFlags                     Property              System.Int32 systemFlags {get;}
uSNChanged                      Property              System.Int64 uSNChanged {get;}
uSNCreated                      Property              System.Int64 uSNCreated {get;}
whenChanged                     Property              System.DateTime whenChanged {get;}
whenCreated                     Property              System.DateTime whenCreated {get;}


Now we just have to filter on the property CanonicalName.
# Get the property CanonicalName for each Organizational Unit
Get-ADOrganizationalUnit -Filter * -Properties CanonicalName | Select-Object -Property CanonicalName


Output:
CanonicalName
-------------
FX.LAB/Domain Controllers
FX.LAB/TEST
FX.LAB/TEST/Groups
FX.LAB/MTL
FX.LAB/Administration
FX.LAB/Administration/Local
FX.LAB/Administration/Global
FX.LAB/Administration/Admin Users
FX.LAB/Administration/ServiceAccounts
FX.LAB/Administration/Test Jonathan OU
FX.LAB/TEST/Users
FX.LAB/TEST/Servers
FX.LAB/Winter Scripting Games 2014
FX.LAB/Winter Scripting Games 2014/Event3
FX.LAB/Winter Scripting Games 2014/Event3/Finance Department




Get-ADObject

The Get-ADObject cmdlet gets an Active Directory object or performs a search to retrieve multiple objects.

# Get Organizational Unit objects
Get-ADObject -Filter { ObjectClass -eq 'organizationalunit' }


# Get Organizational Unit objects
Get-ADObject -Filter { ObjectClass -eq 'organizationalunit' } -Properties CanonicalName | Select-Object -Property CanonicalName

Output:
CanonicalName
-------------
FX.LAB/Domain Controllers
FX.LAB/TEST
FX.LAB/TEST/Groups
FX.LAB/MTL
FX.LAB/Administration
FX.LAB/Administration/Local
FX.LAB/Administration/Global
FX.LAB/Administration/Admin Users
FX.LAB/Administration/ServiceAccounts
FX.LAB/Administration/Test Jonathan OU
FX.LAB/TEST/Users
FX.LAB/TEST/Servers
FX.LAB/Winter Scripting Games 2014
FX.LAB/Winter Scripting Games 2014/Event3
FX.LAB/Winter Scripting Games 2014/Event3/Finance Department


ADSI/NET

Finally, the ADSI method! This technique is a bit more complex, but this does not require any module/snapin and can be run from PowerShell without any pre-requisites.

$info = ([adsisearcher]"objectclass=organizationalunit")
$info.PropertiesToLoad.AddRange("CanonicalName")
$info.findall().properties.canonicalname




Thanks for reading! If you have any questions, leave a comment or send me an email at fxcat@lazywinadmin.com. I invite you to follow me on Twitter @lazywinadm / Google+ / LinkedIn. You can also follow the LazyWinAdmin Blog on Facebook Page and Google+ Page.

26 comments:

  1. This comment has been removed by a blog administrator.

    ReplyDelete
  2. Good post buddy, I will make sure to reference this in the future! Cheers :)

    ReplyDelete
  3. Just followed your post in the lab, works great, learned something new :)

    ReplyDelete
  4. That was very easy steps and was has been very helpful.

    ReplyDelete
  5. Is there a way to modify this to pull the servername info from a txt file, then process this txt file to see if NLA is enabled? Then pipe the results (whether its enabled or not) into another txt file? Thanks.

    ReplyDelete
  6. Hi Joel,


    It's pretty easy, something like this should do it:


    Output to a txt file
    Get-NetworkLevelAuthentication -ComputerName (Get-Content d:\serverlist.txt) | Out-File d:\result.txt


    Output to a csv file
    Get-NetworkLevelAuthentication -ComputerName (Get-Content d:\serverlist.txt) | Export-Csv d:\result.csv



    In this example, all your servers need to be listed in the serverlist.txt


    Hope this help

    ReplyDelete
  7. I believe this should work. Thanks for the quick response.

    ReplyDelete
  8. No pb, let me know if you have other question.


    note: I updated the blog post to add the example

    ReplyDelete
  9. Have you seen this error message before (via powershell v1.0):

    PS C:\powershell> . .\Get-Set-NetworkLevelAuthentication.ps1
    The "=" operator is missing after a named argument.
    At C:\powershell\Get-Set-NetworkLevelAuthentication.ps1:56 char:32
    + [Parameter(ValueFromPipeline) <<<< ]
    + CategoryInfo : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : MissingEqualsInNamedArgument

    ReplyDelete
  10. Hey Joel,

    Interesting, never saw this message before.

    Which version of PowerShell do you run ? ($psversiontable will tell you)

    The functions requires at least version 3.

    Give a try with the version available on github

    https://github.com/lazywinadmin/PowerShell/blob/master/TOOL-Get-Set-NetworkLevelAuthentication/Get-Set-NetworkLevelAuthentication.ps1

    ReplyDelete
  11. I've seemed to have success with just running the "Getting the NLA information" command. Any chance you can point me in the direction as to how to output the servername (or IP address) along with the result (whether it 0 = no, or 1 = yes (NLA enabled) )? Thanks.

    $ComputerName = (Get-Content c:\powershell\serverlist.txt)

    # Getting the NLA information

    (Get-WmiObject -class "Win32_TSGeneralSetting" -Namespace root\cimv2\terminalservices -ComputerName $ComputerName -Filter "TerminalName='RDP-tcp'").UserAuthenticationRequired

    Export-Csv c:\powershell\result.csv

    ReplyDelete
  12. I guess you are running v2.

    Anyway, you can do this way (I tested in v2)

    Get-WmiObject -class "Win32_TSGeneralSetting" -Namespace root\cimv2\terminalservices -ComputerName (Get-Content c:\powershell\serverlist.txt) -Filter "TerminalName='RDP-tcp'"| Select-Object __SERVER,@{name="NLAEnabled";Expression={$_.UserAuthenticationRequired -as [bool]}} | Export-Csv c:\powershell\result.csv

    ReplyDelete
  13. Thanks for the article

    what will be needed to "fix" the citrix side so you can't connect from it instead of disabling the NLA on the client side ?


    Haim

    ReplyDelete
  14. And how do you pass authentication to a server that is not a member of the domain?

    ReplyDelete
  15. Hey RykeAbel,
    Never tried that. Looks like this guys did some work with a WorkGroup box:
    http://www.mcbsys.com/techblog/2011/03/remote-wmi-to-a-workgroup-server-2008-r2/



    Hope this help

    ReplyDelete
  16. See http://blogs.technet.com/b/askcore/archive/2010/04/20/reason-for-access-denied-error-in-powershell-using-get-wmiobject-calls-to-a-remote-windows-server-2008-failover-cluster-node.aspx if you are getting Access Denied responses.

    ReplyDelete
  17. how to use the remote option only me not other person allow in my system

    ReplyDelete
  18. Get-ADOrganizationalUnit -Filter * -Properties Name | Select-Object -Property Name | sort-object Name, ascending

    This worked like a charm for me

    ReplyDelete
  19. Thanks Elemer, yep this works too but only the name of the OU will output.
    In my case, my coworker wanted the CanonicalName

    ReplyDelete
  20. Hi. I'd like to check how many users there is in each OU. Could you please help?

    ReplyDelete
  21. thanks for your comment Izzie, you can do something like this

    Get-ADOrganizationalUnit -Filter * -SearchBase "" | ForEach-Object {

    [pscustomobject][ordered]@{

    OU = $_.DistinguishedName

    UsersCount = ((Get-ADUser -SearchScope OneLevel -SearchBase $_.DistinguishedName -filter *)|Measure-Object).count

    }

    }



    On the Get-ADOrganizationUnit cmdlet, the SearchBase is optional.
    On the Get-ADUser Cmdlets, the SearchScope Onelevel is optional.


    Hope this help

    ReplyDelete