📜 ⬆️ ⬇️

10 Active Directory Administrative Tasks Solved With PowerShell

Jeffery Hicks prepared an article on Windows IT Pro about using PowerShell to administer AD. As a starting point, the author decided to take 10 typical AD administration tasks and consider how to simplify them using PowerShell:
  1. Reset user password
  2. Activate and deactivate accounts
  3. Unlock User Account
  4. Delete your account
  5. Find empty groups
  6. Add users to a group
  7. List the group members
  8. Find obsolete computer accounts
  9. Deactivate a computer account
  10. Find computers by type


In addition, the author maintains a blog (of PowerShell, of course), we recommend to take a look - jdhitsolutions.com/blog . And the most relevant you can get from his twitter.com/jeffhicks .
So, below is a translation of the article “Top 10 Active Directory Tasks Solved with PowerShell”.

Managing Active Directory (AD) with Windows PowerShell is easier than you think, and I want to prove it to you. You can simply take the scripts below and use them to solve a number of AD management tasks.
')

Requirements



To use PowerShell to manage AD, you must meet several requirements. I'm going to demonstrate how cmdlets for AD work on the example of a computer on Windows 7.
To use cmdlets, you must have a Windows Server 2008 R2 level domain controller, or you can download and install Active Directory Management Gateway Service on legacy DCs inherited from domain controllers. Read the documentation carefully before installation; reboot CD is required.
On the client side, download and install Remote Server Administration Tools (RSAT) for either Windows 7 or Windows 8 . In Windows 7, you will need to open the Programs section in the Control Panel and select Turn Windows Features On or Off . Find Remote Server Administration Tools and expand the Role Administration Tools section. Select the appropriate items for AD DS and AD LDS Tools, especially note that the Active Directory Module for Windows PowerShell should be selected, as shown in Figure 1. (In Windows 8, all tools are selected by default). Now we are ready to work.


Figure 1 Turning on AD DS and AD LDS Tools

I am logged in as a domain administrator. Most of the cmdlets I will show will allow you to specify alternative credentials. In any case, I recommend reading the help ( Get-Help ) and examples that I will demonstrate below.
Start a PowerShell session and import the module:

PS C:\> Import-Module ActiveDirectory 


The import creates a new PSDrive, but we will not use it. However, you can see which commands are available in the imported module.

 PS C:\> get-command -module ActiveDirectory 


The beauty of these commands is that if I can use the command for one AD object, then it can be used for 10, 100 and even 1000. Let's see how some of these cmdlets work.

Task 1: Reset User Password



Let's start with a typical task: reset a user password. This can be done easily and simply via the Set-ADAccountPassword cmdlet The tricky part is that the new password must be specified as a secure string: a piece of text that is encrypted and stored in memory for the PowerShell session. First, create a variable with a new password:
 PS C:\> $new=Read-Host "Enter the new password" -AsSecureString 


Then, enter the new password:

 PS C:\> 


Now we can retrieve the account (using samAccountname is the best option) and set a new password. Here is an example for the user Jack Frost:

 PS C:\> Set-ADAccountPassword jfrost -NewPassword $new 


Unfortunately, in the case of this cmdlet there is a bug: -Passthru , -Whatif , and –Confirm do not work. If you prefer a short cut, try the following:

 PS C:\> Set-ADAccountPassword jfrost -NewPassword (ConvertTo-SecureString -AsPlainText -String "P@ssw0rd1z3" -force) 


As a result, I need Jack to change the password the next time I log in, and I modify my account using Set-ADUser .

 PS C:\> Set-ADUser jfrost -ChangePasswordAtLogon $True 


The cmdlet results are not written to the console. If this needs to be done, use –True . But I can find out whether the operation was successful or not by retrieving the user name using the Get-ADUser cmdlet and specifying the PasswordExpired property, as shown in Figure 2.


Fig. 2. Results of the Get-ADUser Cmdlet cmdlet with the PasswordExpired property

Bottom line: resetting a user's password using PowerShell is not at all difficult. I admit that resetting the password is also easy via the Microsoft Management Console (MMC) snap-in in Active Directory Users and Computers . But using PowerShell is suitable if you need to delegate a task, you do not want to deploy the above-mentioned snap-in, or reset the password during a large automated IT process.

Task 2: Activate and deactivate accounts



And now let's deactivate the account. We continue to work with Jack Frost. This code uses the –Whatif parameter, which you can see on other cmdlets that make changes to test my command without running it.

 PS C:\> Disable-ADAccount jfrost -whatif What if: Performing operation "Set" on Target "CN=Jack Frost, OU=staff,OU=Testing,DC=GLOBOMANTICS,DC=local". 


And now we deactivate for real:

 PS C:\> Disable-ADAccount jfrost 


And when the time comes to activate the account, which cmdlet will help us?

 PS C:\> Enable-ADAccount jfrost 


These cmdlets can be used in a pipelined expression, allowing you to activate or deactivate as many accounts as you want. For example, this code deactivates all accounts in the sales department (Sales)

 PS C:\> get-aduser -filter "department -eq 'sales'" | disable-adaccount 


Of course, writing a filter for Get-ADUser is quite difficult, but it is here that using the –Whatif parameter with the Disable-ADAccount cmdlet comes to the rescue.

Task 3: Unlock User Account



Consider the situation when Jack blocked his account, trying to enter a new password. In order to try to find his account through the GUI, the unlock procedure can be performed using a simple command.

 PS C:\> Unlock-ADAccount jfrost 


The cmdlet also supports the -Whatif and -Confirm parameters .

Task 4: Delete Account



No matter how many users you delete, this is easy to accomplish using the Remove-ADUser cmdlet . I do not want to remove Jack Frost, but if I wanted to, I would use the following code:

 PS C:\> Remove-ADUser jfrost -whatif What if: Performing operation "Remove" on Target "CN=Jack Frost,OU=staff,OU=Testing,DC=GLOBOMANTICS,DC=local". 


Or I can enter several users and delete them with one simple command:

 PS C:\> get-aduser -filter "enabled -eq 'false'" -property WhenChanged -SearchBase "OU=Employees, DC=Globomantics,DC=Local" | where {$_.WhenChanged -le (Get-Date).AddDays(-180)} | Remove-ADuser -whatif 


This command will find and delete all deactivated accounts of the unit (OU) Employees that have not changed for 180 days or more.

Task 5: Search for empty groups



Managing groups is endless and ungrateful. There are many ways to find empty groups. Some expressions may work better than others, depending on your organization. The code below will allow you to find all groups in the domain, including the built-in ones.

 PS C:\> get-adgroup -filter * | where {-Not ($_ | get-adgroupmember)} | Select Name 


If you have groups with hundreds of members, then using this command can take a long time; Get-ADGroupMember checks each group. If you can limit or customize, it will be better.
Here is another approach:

 PS C:\> get-adgroup -filter "members -notlike '*' -AND GroupScope -eq 'Universal'" -SearchBase "OU=Groups,OU=Employees,DC=Globomantics, DC=local" | Select Name,Group* 


This command finds all Universal groups that do not have membership in OU Groups and displays some of the properties. The result is shown in Figure 3.

Fig. 3. Search and filter universal groups

Task 6: Add Users to a Group



Let's add Jack Frost to the Chicago IT group:

 PS C:\> add-adgroupmember "chicago IT" -Members jfrost 


Yes, everything is so simple. You can also easily add hundreds of users to groups, although in my opinion this is slightly inconvenient:

 PS C:\> Add-ADGroupMember "Chicago Employees" -member (get-aduser -filter "city -eq 'Chicago'") 


I used the parenthetical pipelined expression to find all users who have a City property in Chicago. The code in brackets is executed, and the resulting objects are passed to the –Member parameter. Each user object is added to the Chicago Employees group. It doesn't matter if we deal with 5 or 5,000 users, group membership updates take only a few seconds. This expression can also be written using ForEach-Object , which can be more convenient:

 PS C:\> Get-ADUser -filter "city -eq 'Chicago'" | foreach {Add-ADGroupMember "Chicago Employees" -Member $_} 


Task 7: List the group members

You may want to know who is in a particular group. For example, you should periodically find out who is in the Domain Admins group:

 PS C:\> Get-ADGroupMember "Domain Admins" 


Figure 4 shows the result.


Fig. 4. Members of Domain Admins

The cmdlet prints an AD object for each group member. And what to do with nested groups? My Chicago All Users group is a collection of nested groups. To get a list of all accounts, I just have to use the –Recursive parameter.

 PS C:\> Get-ADGroupMember "Chicago All Users" -Recursive | Select DistinguishedName 


If you want to go the other way — find out which groups the user is in — use Member Member property:

 PS C:\> get-aduser jfrost -property Memberof | Select -ExpandProperty memberOf CN=NewTest,OU=Groups,OU=Employees, DC=GLOBOMANTICS,DC=local CN=Chicago Test,OU=Groups,OU=Employees, DC=GLOBOMANTICS,DC=local CN=Chicago IT,OU=Groups,OU=Employees, DC=GLOBOMANTICS,DC=local CN=Chicago Sales Users,OU=Groups,OU=Employees, DC=GLOBOMANTICS,DC=local 


I used the -ExpandProperty parameter to print MemberOf names as strings.

Task 8: Find obsolete computer accounts



I am often asked this question: “How to find outdated computer accounts?”. And I always answer: “And what is obsolete for you?” Companies differently determine when a computer account (or user, whatever) is considered obsolete and is not subject to further use. As for me, I pay attention to those accounts whose passwords have not changed for a certain period of time. This period is 90 days for me - if the computer has not changed the password along with the domain for this period, most likely it is offline and outdated. The Get-ADComputer cmdlet is used :

 PS C:\> get-adcomputer -filter "Passwordlastset -lt '1/1/2012'" -properties *| Select name,passwordlastset 


The filter works fine with a hard value, but this code will be updated for all computer accounts that have not changed their passwords since January 1, 2012. The results are shown in Figure 5.


Fig. 5. Find obsolete computer accounts

Another option: suppose you are at least at the functional level of the Windows 2003 domain. Set the filter by the LastLogontimeStamp property. This value is the number of 100 nanosecond intervals from January 1, 1601, and stored in GMT, so working with this value is slightly difficult:

 PS C:\> get-adcomputer -filter "LastlogonTimestamp -gt 0" -properties * | select name,lastlogontimestamp, @{Name="LastLogon";Expression={[datetime]::FromFileTime ($_.Lastlogontimestamp)}},passwordlastset | Sort LastLogonTimeStamp 


I took responsibility and added a custom property that takes the value of LastLogontimeStamp and converts it into the usual format. Figure 6 shows the result.


Fig. 6. Convert the LastLogonTimeStamp value to the usual format

To create a filter, I need to convert the date, for example, January 1, 2012, into the correct format. Conversion is carried out in FileTime:

 PS C:\> $cutoff=(Get-Date "1/1/2012").ToFileTime() PS C:\> $cutoff 129698676000000000 


Now I can use this variable in the filter for Get-ADComputer :

 PS C:\> Get-ADComputer -Filter "(lastlogontimestamp -lt $cutoff) -or (lastlogontimestamp -notlike '*')" -property * | Select Name,LastlogonTimestamp,PasswordLastSet 


The above code finds the same computers that were shown in Figure 5.

Task 9: Deactivate the computer account



Perhaps when you find inactive or outdated accounts, you will want to deactivate them. Make it pretty simple. We will use the same cmdlet used in working with user accounts. You can refine it by using the samAccountname account.

 PS C:\> Disable-ADAccount -Identity "chi-srv01$" -whatif What if: Performing operation "Set" on Target "CN=CHI-SRV01, CN=Computers,DC=GLOBOMANTICS,DC=local". 


Or using a pipeline expression:

 PS C:\> get-adcomputer "chi-srv01" | Disable-ADAccount 


I can also use my code to find outdated accounts and deactivate all of them:

 PS C:\> get-adcomputer -filter "Passwordlastset -lt '1/1/2012'" -properties *| Disable-ADAccount 


Task 10: Find computers by type



I am also often asked how to find computer accounts by type, for example, servers or workstations. For your part, this requires some creativity. In AD, there is nothing that distinguishes a server from a client, except the OS. If your computer is running Windows Server 2008, you will have to do a few additional steps.
First you need to get a list of operating systems, and then we filter accounts by existing operating systems.

 PS C:\> Get-ADComputer -Filter * -Properties OperatingSystem | Select OperatingSystem -unique | Sort OperatingSystem 


The results are shown in Figure 7.


Fig. 7. Extract OS List

I want to find all the computers on which the server OS is running:

 PS C:\> Get-ADComputer -Filter "OperatingSystem -like '*Server*'" -properties OperatingSystem,OperatingSystem ServicePack | Select Name,Op* | format-list 


The results are shown in Figure 8.



Like other AD Get cmdlets, you can configure search parameters and limit the query to individual OUs, if necessary. All the expressions that I showed can be integrated into large PowerShell expressions. For example, you can sort, group, apply filters, export to CSV, or create and send HTML email reports - all from PowerShell! At the same time you do not have to write a single creak.
Here's a bonus for you: a report on the age of a user password (user password-age report), saved in an HTML file:

 PS C:\> Get-ADUser -Filter "Enabled -eq 'True' -AND PasswordNeverExpires -eq 'False'" -Properties PasswordLastSet,PasswordNeverExpires,PasswordExpired | Select DistinguishedName,Name,pass*,@{Name="PasswordAge"; Expression={(Get-Date)-$_.PasswordLastSet}} |sort PasswordAge -Descending | ConvertTo-Html -Title "Password Age Report" | Out-File c:\Work\pwage.htm 


Although this expression may look a bit intimidating, with minimal knowledge of PowerShell it is easy to use. And there remains only the last tip: how to define a custom property called PasswordAge . The value is the gap between today and the PasswordLastSet property. Then I sort the results for my new property. Figure 9 shows the output for my small test domain.



Upd:
The post contains a translation of an article on the WindowsITPro portal .
Top 10 Active Directory Tasks Solved with PowerShell

Bonus: PowerShell for system administration purposes \\ Articles on Habré


How do you use PowerShell to simplify your work?

Source: https://habr.com/ru/post/160837/


All Articles