Skip to main content

Posts

Showing posts from 2009

Get group members of large groups via Powershell

Get group members of large groups via Powershell I have always been aware that getting the group membership of large groups has been a challenge and have always managed to avoid addressing the issue.  (Is that what we call the 'Too Hard' pile???) Well, I have had a reason to find this out again, but this time I have Powershell to help me out! Why is this such an issue I hear you ask... this link  expalins why.  In a nut shell, you will only every return a maximum of 1500 members for a group, 1000 if you are querying Windows 2000.  I cannot take any credit for the soulution, I can only pass on a now ancient (in poweshell terms that is) Monad link to how to enumerate all the members of a group from /\/\o\/\/ .  As you will see, this link refers to Monad, the pre-release name for powershell.  Please follow the link above or more from /\/\o\/\/ can be found at thepowershellguy.com meanwhile, I have added my own comments to his script below... #get the group $group = [ads

Computer Password Changes in AD

In trying to resolve an issue with regards to computers loosing thier trust relationship with the domain, I found this increadibly good explaination  of how passwords are used and changed in AD.  It goes a long way to explain where is the password change is initiated (the computer, not a DC), what is required to be in place before the change can happen and how it works around an issues it may face. Thanks Manish Singh (from the Directory Services team) for such a detailed post. Added to links too!

Manage Shadow Group Membership - Powershell Function

Manage Shadow Group Membership - PowerShell Function I looked at a quick script to update a shadow group here , and then thought, this would make a good function. I have used my function template (refer to that post if you want to know more about how to format a function), to build up a reusable script to update group membership based on user and computer object location in AD. A traditional shadow group is all members of an OU. In my mind, there are a few assumptions to this statement. Being that you have taken the time to create an OU, put objects in it, and created a group to mirror those objects, you probably have only 1 type of object (i.e. user) and they are all similar in some respect (i.e. same office location). This function takes that in mind and only updates groups with users or computers - not other groups etc. Moving away from the traditional meaning of shadow group, I have added (for my own benefit as I required the functionality) a parameter to change the searchsco

Powershell v2 Function Template

Powershell v2 Function Template Powershell v2 has updated what you can do with creating functions over Powershell V1. The whole function experience has been updated to a cmdlet like feel with error handling, parameter validation, help creation and of course, tab completion! The following is a bare bones template that I've commented inline for easy reading! function new-template { <# .SYNOPSIS    Brief description of what the function does .DESCRIPTION    A better description .NOTES    Function Name : new-template    Author : Adam Stone    Requires : PowerShell V2 .LINK    http://adadmin.blogspot.com/ .EXAMPLE    Simple usage    PS C:\> new-template -args values .EXAMPLE    Simple usage    PS C:\> new-template -args values values etc .PARAMETER first    A description of the first parameter .PARAMETER targetdomain    A description of the sedond parameter #> #parameter validataion param (    #define the position of the parameter if required, sp

Manage Shadow Group Membership with powershell AD Cmdlets

Manage Shadow Group Membership with powershell AD Cmdlets Sometimes, in our Active Directory structure, we need a group to reflect the contents of an OU. One example of this is If you organise you users and computers in location specific OU's and need to use RODC password replication policy. In this script I use PowerShell v2 AD cmdlets to enumerate group membership and OU membership and then use compare-object to work out the differences. Finally the switch reads if the additional user was found in the group or the OU and either adds or removed the member accordingly. This script uses get-aduser, but get-adcomputer will work just as well. I am wouking on a more comprehensive solution using get-adobject to deal with multiple object types. $Group = "shadowgroup" $OU = "OU=ShadowOU,DC=domain,DC=com" $users = $(get-aduser -SearchBase $OU -filter "*") $groupmembers = Get-ADGroupMember -Identity $Group switch (Compare-Object -ReferenceObject $gro

Get-ADGroup - AD Cmdlet Reference

Get-ADGroup A simple cmdlet for powershell 2 AD management pack to get group information in one line. Example usage get-adgroup -identity "domain admins" get-adgroup -filter 'GroupScope -eq "Universal"' Define the parameters Identity takes a range of identifiers for the object. These include "Distinguished Name", "GUID", "SID", and "samaccountname". As all the cmdlets have been designed for interoperability, I find it best to use output from other commands like get-aduser. Full help file here . In a script This script gets detailed information about all the groups that user1 is a direct member of. get-aduser user1 -Properties memberof | select -expandproperty memberof | foreach {get-adgroup $_} Powershell without the Management pack To emulate the second example above, get all universal groups, I have chosen my GC search script  to return the information.  Note, all group type values have been list

Select-Object -expandproperty ... a time saver!!!!

Select-Object -expandproperty ... a time saver!!!! Have you ever run a powershell command and used select-object to filter the returned object?  If you have you will know that even if you only have one value in the select, you still have to refer to the property name to return the values.  Example : I want a list of all my enabled DC's PS C:\temp> $dcs = get-ADDomainController -filter {enabled -eq $True} | select HostName PS C:\temp> $dcs HostName -------- DC01.DOMAIN.COM DC02.DOMAIN.COM DC03.DOMAIN.COM DC04.DOMAIN.COM But to get to the first hostname I have to write this : $dcs[0].hostname If I were to use -expandproperty as below : PS C:\temp> $dcs = get-ADDomainController -filter {enabled -eq $True} | Select-Object -ExpandProperty hostname PS C:\temp> $dcs DC01.DOMAIN.COM DC02.DOMAIN.COM DC03.DOMAIN.COM DC04.DOMAIN.COM I now have an array of server names that I can simply push through a foreach, without the '.hostname'!

Enabling PowerShell Remoting and Remote Administration - Windows 2008 R2 Server Core

Enabling Powershell Remoting and Remote Administration - Windows 2008 R2 Server Core Following on from my post Enable WinRM via Group Policy , there as some follow on tasks to ensure server core is manageable via powershell and server manager. Add Firewall Rule To start with, to allow GUI remote management of the event viewer, another firewall rule needs to be added : Computer Configuration / Policies / Windows Settings / Security Settings / Windows Firewall with Advanced Security Create an Inbound Rule allowing the predefined group 'Remote Event Log Management' Install powershell and packs Next, as server core is the only version of Windows Server 2008 R2 that does not install Powershell V2 by default, we need to install powershell and which ever cmdlet management pack we need. In this case I am only going to install the server manager and AD cmdlets. Winrs -r:$dc.name Ocsetup MicrosoftWindowsPowerShell Winrs -r:$dc.name Ocsetup ServerManager-PSH-Cmdlets Winrs -

Trigger KCC on all Domain Controllers

Trigger KCC on all Domain Controllers If you need to ensure all DC's have built the latest topology, a quick powershell one-liner (that's powershell v1 and v2).  foreach ($dc in [System.DirectoryServices.ActiveDirectory.domain]::getcurrentdomain().FindAllDomainControllers()){$dc.CheckReplicationConsistency()} Check out all the DC Methods that can be run in this way.

Add-ADDomainControllerPasswordReplicationPolicy - AD Cmdlet Reference

Add-ADDomainControllerPasswordReplicationPolicy This cmdlet is there to manage the Password Replication Policy for RODC's.  A handy tool as without the AD management pack, you can only do this at the command line with repadmin! Example usage Add-ADDomainControllerPasswordReplicationPolicy -identity $RODC -AllowedList $group Define the parameters Both identity and AllowedList (also, DeniedList) take a range of identifiers for the object. These include "Distinguished Name", "GUID", "SID", and "samaccountname". As all the cmdlets have been designed for interoperability, I find it best to use output from other commands like get-aduser or in the case below, Get-ADDomainController. In a script In this script, I get every RODC, and firestly build a list of group names from the first 6 characters of the RODC name.  I then get the allowed list from the RODC and check my built list against the PRP entries.  For any that are not already memb

Get-ADDomainController - AD Cmdlets Reference

Get-ADDomainController Get-ADDomainController is useful to easily return all, or a subset of your domain controllers.  This can be easily filtered by type, OS, AD Site, or a number of other values. Example usage #get all read only DC's Get-ADDomainController -filter {isreadonly -eq $true} # get the domain controller DC1 Get-ADDomainController -identity "DC1" # get the PDCE for the domain Get-ADDomainController -Discover -Service "PrimaryDC"} # get a GC but force it to rediscover (clear any cached DC) Get-ADDomainController -Discover -Service "GlobalCatalog" -ForceDiscover Define the parameters Identity takes a range of identifiers for the object. These include "Distinguished Name", "GUID", "SID", and "samaccountname". Service takes the following : PrimaryDC or 1 GlobalCatalog or 2 KDC or 3 TimeService or 4 ReliableTimeService or 5 ADWS or 6 Filter uses the format {isreadonly -eq $true

Add-ADGroupMember - AD Cmdlets Reference

Add-ADGroupMember Quite an easy one to start with, but quite handy too. Saves a few lines of code from ps1. Example usage Add-ADGroupMember -identity "Group name" -members "new group member" Add-ADGroupMember "Group name" "list of new group member" Define the parameters Both identity and members take a range of identifiers for the object. These include "Distinguished Name", "GUID", "SID", and "samaccountname". As all the cmdlets have been designed for interoperability, I find it best to use output from other commands like get-aduser. In a script #set the group name $Group = "All Managers" #get the objects that you want to add to the group (in this case, users with Manager in the description) $users = get-aduser -filter {description -like "*Manager*"} #Add the users to the group Add-ADGroupMember $Group $users Powershell without the Management pack How you gener

AD Cmdlets reference

AD Cmdlets reference Over the next few weeks, my aim is to add a reference to all the AD cmdlets that I am using and the equivilent Poswershell 1 code (or indeed powershell 2 without the AD management pack).  I am finding that I am doing a lot of conversion betweek the 2 versions at the moment and would find a quick reference handy, and if it is for anybody else, the great! First Cmdlet coming soon....any suggestions?

Searching AD using .net and a GC

Searching AD using .net and a Global Catalog (GC) Server Although I have been recently been exploring the world of R2 and AD-cmdlts, I have re-visited .net to search a the whole forest in one quick step.  As A GC holds a subset of information on all objects in the forest, we can query any GC in the forest to return these values.  Here, I am doing a search for a specific UPN, but the filter can inculde any attribute stored on the GC. $upn= "first.last@domain.name" $Forest = [System.DirectoryServices.ActiveDirectory.forest]::getcurrentforest() $GC = $forest.FindGlobalCatalog() $searcher = $gc.GetDirectorySearcher() $searcher.filter = "(userprincipalname=$upn)" $Results = $Searcher.FindAll() The rest of the script is the same as how we ended up in my AD Searcher You might not want to find any GC in the forest, you might want to only choose one from a particular site. As $forest.FindGlobalCatalog() has an option for this, the command simply becomes $GC

Installing and using the Active Directory Management Gateway Service (ADMGS)

ADMGS - How to install on Server 2003 and Server 2008 From someone who has done a lot of AD related scripting in powershell v1, it has taken me a while to get to grips with using the new AD cmdlets in PowerShell v2.  Needless to say, I have started 'dipping my toe' into the vast 'sea of cmdlets' now available and am finding them quite useful.  So much so, that enabling the ability to use the cmdlets in my older domains has become essential.   I no longer want to have to write v1 and v2 scripts, or more specifically, ad cmdlet and non-ad-cmdlet enabled scripts.  Here enters the 'Active Directory Management Gateway Service'  .This provides the connectivity for the AD-cmdlets to communicate with a domain controller in your domain. Pre-requisites For a small installer, this guy need a fair few prerequisites - each OS version being slightly different. Windows 2008 (tested on 32bit) It is best that you have SP2 installed as there is an issue with Windows

Finding out what 'SearchFlags' are set on you AD attributes

Whilst doing some research into indexed attributes, I posted this  a while back on how to find your index attributes.  Since then, I have looked a little deeper into what indexing really means and found this excellent explanation on the numbers that can be found in the searchflags attribute of a schema object. Using Florian’s reference, I built the following script (which is both powershell v1 and v2 compatible) to get the schema attributes from the forest schema and return (among other things) the breakdown of your attributes search flags. $forest = [System.DirectoryServices.ActiveDirectory.forest]::getcurrentforest() $schema = [ADSI]('LDAP://CN=Schema,CN=Configuration,dc=' + ($($forest).name -replace "[.]",",dc=")) $attributes = $schema.psbase.children | where {$_.objectClass -eq "attributeSchema"} $collection = @() foreach ($attr in $attributes){ $store = "" | select "Name","lDAPDisplayName","singlev

Hash Tables - DC operating systems

I have been meaning to get my head around a lot of different aspects of powershell, one of which is hash tables.  As we are currently going through a DC upgrade, I wanted to know how many DC's we had of each different operating system.  I wondered if hash tables would help me. First, I got all DC's in my domain :  $DClist = get-ADDomainController -server domain.com -filter {enabled -eq $true} You may notice the get-ad portion of the command....this means that this command runs only on powershell 2 when connected to an Windows 2008 R2 DC or a 2003 / 2008 DC with ADMGS installed.  So, $DCList is now all the DC's from domain.com (-server domain.com) that are set to enabled (-filter {enabled -eq $true}).  NOTE: The only DC's that are not enabled are pre-staged RODC accounts ... by that i mean accounts that have been created but the server has not come online yet.  These servers do not have any OS information in them anyway. It is more helpful to filter these w

RODC Password Replication Policy

I have been fortunate enough to be involved in quite a large RODC deployment in a Windows 2008 domain. Even more fortunate is that we are currently upgrading this domain to R2 so I am getting the chance to try out the new powershell 2 AD cmdlets. I have been looking quite a lot into RODC operations, and the importance of the Password Replication Policy (PRP from now on) component has become increasingly more apparent. My first thoughts of PRP were entirely user based. "It allows users to logon to a remote site when the WAN link is down" was my impression. But, when a user logs on to a domain from a trusted computer, there is 2 parts to the authentication - user AND computer. Therefore it is just as important to add the computer objects to the allow PRP as it is the users. While you are there, add any server that is in the same site as the RODC as they will need to authenticate too. My preferred way of doing this create 3 groups and add them to the PRP policy : all users, al

How to find out what attributes in your AD domain are indexed

Every wondered why some queries return much faster than others?  If you search on attributes that are indexed, your DC returns the value much quicker.  How can you find out what attributes are indexed?  use the following  : If you find that your attribute is not being indexed, take a look  here  to find out how to add it to the index. $Collection = @() $domain = [System.DirectoryServices.ActiveDirectory.domain]::getcurrentdomain() $ObjectCategory = "attributeSchema" $ObjectProplist = "name" $LdapQuery = "(&(objectCategory=$ObjectCategory)(searchFlags:1.2.840.113556.1.4.803:=1))" ($domain).name $LDAPdomain = [ADSI]('LDAP://CN=Schema,CN=Configuration,dc=' + ($($domain).name -replace "[.]",",dc=")) $Searcher = New-Object System.DirectoryServices.DirectorySearcher($LDAPdomain, $LdapQuery, $ObjectProplist) $Searcher.pagesize = 1000 $Results = $Searcher.FindAll() foreach ($Object in $Results){    $Store = "&quo

Active Directory Searcher - Part 3

In the final part of this series, I will look at dealing with the lastlogontimestamp attribute and easily outputting the data you have gathered to a file. Part 2 left us with : $domains = [System.DirectoryServices.ActiveDirectory.forest]::getcurrentforest().get_domains() $ObjectCategory = "user" $ObjectProplist = "name","samaccountname","whencreated" $LdapQuery = "(&(objectCategory=$ObjectCategory)(name=ad*))" foreach ($domain in $domains){       ($domain).name       $LDAPdomain = $domain.GetDirectoryEntry()       $Searcher = New-Object System.DirectoryServices.DirectorySearcher($LDAPdomain, $LdapQuery, $ObjectProplist,"subtree")       $Searcher.pagesize = 1000       $Results = $Searcher.FindAll()       foreach ($Object in $Results){             foreach ($prop in $ObjectProplist){                   $Object.Properties.$prop                  }       } } If you have tried to manipulate lastlogontimestamp in VB, you will

Enable Powershell Remoting (WinRM) via Group Policy

I have been doing some testing on enabling WinRM via group policy, being that WinRM is the service that Powershell v2 sets up it remoting capabilities. Here are the GPO settings that you need to configure WinRM .... set the winrm service to auto start Computer Configuration \ Policies \ Windows Settings \ Security Settings \ System Services Windows Remote Management (WS-Management)  set Startup Mode to Automatic start the service incorporated in to the above - you may need a restart. create a winrm listener Computer Configuration / Policies / Administrative Templates / Windows Components / Windows Remote Management (WinRM) / WinRM Service / Allow automatic configuration of listeners IPv4 filter: * * is listen on all addresses, or if you only want a particular IP address to respond use an iprange eg 10.1.1.1-10.1.1.254 - don't forget that this IP range has to be valid for all hosts that fall in the scope of the GPO you are creating.  You can use 10.1.1.1 -

Active Directory Searcher - Part 2

We finished up Part 1  with this script : $LDAPdomain = [ADSI]('LDAP://dc=other,dc=com') $Searcher = New-Object System.DirectoryServices.DirectorySearcher($LDAPdomain,"(objectclass=user)","name","subtree") $Results = $Searcher.FindAll() foreach ($Object in $Results){   $Object.Properties.name } I am going to take things a little further by adding variables which in turn will help remove any hardcoded elements of the script. A quick one first, after running your search for all users, did you notice that you got exactly 1000 results (assuming that you have at least 1000 users in your domain)?  This is the maximum number of records that you can return in one go using LDAP.  What you need to do is tell the searcher to page results by adding this command : $Searcher.pagesize = 1000 This will return the first 1000, but go off and find the next 1000 straight after, and so on. The next thing is to use variables instead of hard coding in the