We can use Active Directory Users and Computers (ADUC) for many things, such as Queries, or the new Active Directory Administrative Center. However, PowerShell and the ActiveDirectory module can do more, we can script some operations, and we can also get results that we can work with further (e.g., in Excel). If I'm using PowerShell directly, I prefer to use PowerShell ISE, which is part of Windows 7.
To use the ActiveDirectory module on a workstation, we must have installed Active Directory Domain Services (AD DS and AD LDS Tools, which is part of RSAT - Remote Server Administration Tools) and enabled the Active Directory Module for Windows PowerShell property. We also need to have the Windows Server 2008 R2 Active Directory Web Services service installed on at least one domain controller.
- General Properties
- Users (user account) - creating and setting values
- Users (user account) - listing accounts and values
- Groups (group)
- Computers (computer account) - listing accounts and values
General Properties
Using AD commands
If we use PowerShell ISE, we must first import the ActiveDirectory module at each runtime to have the commands for Active Directory available.
Import-Module ActiveDirectory
Browsing Active Directory
We can browse AD the same way as the file system. First, we switch to AD and then use commands like dir, cd, etc.
PS C:\> cd ad: PS AD:\> dir Name ObjectClass DistinguishedName ---- ----------- ----------------- firm domainDNS DC=firm,DC=local Configuration configuration CN=Configuration,... Schema dMD CN=Schema,CN=Conf... ForestDnsZones domainDNS DC=ForestDnsZones... DomainDnsZones domainDNS DC=DomainDnsZones... PS AD:\> cd 'DC=firm,DC=local' PS AD:\DC=firm,DC=local>
Information about the current domain
Get-ADDomain
Information about domain controllers
$dc = Get-ADDomainController -Filter * $dc | FT Name,Site,OperationMasterRoles,OperatingSystem,IsGlobalCatalog -AutoSize
Users (user account) - creating and setting values
Creating a user
If we have an Exchange server, we might prefer to use a command that creates the account and the mailbox at the same time. We create the user with the default password 123456 and specify the container in which the account will be created.
$pass = ConvertTo-SecureString -AsPlainText -Force -String '123456'
New-ADUser bouska -Name 'Petr Bouška' -SamAccountName 'bouska' -Path 'ou=Firm,dc=firm,dc=local' -UserPrincipalName 'bouska@firm.local' -GivenName 'Petr' -Surname 'Bouška' -AcountPassword $pass -Enabled $true
Setting users to change their password at next logon
To set the ChangePasswordAtLogon option, the PasswordNeverExpires setting must not be set.
Get-ADUser -Filter * -SearchBase "OU=Firm,DC=firm,DC=local" | Set-ADUser -PasswordNeverExpires $false Get-ADUser -Filter * -SearchBase "OU=Firm,DC=firm,DC=local" | Set-ADUser -ChangePasswordAtLogon $true
Users (user account) - listing accounts and values
Displaying all user properties
Get-ADUser bouska -Properties *
List of users and the number of bad password attempts
Get-ADUser -Filter * -Properties badPwdCount | FT Name,badPwdCount,Enabled
List of users who have ChangePasswordAtLogon set
When we want to display a list of users who have the ChangePasswordAtLogon parameter set (which we can set using PowerShell or ADUC), we find that there is no such LDAP attribute, so we cannot display those users. What actually happens is that when we set ChangePasswordAtLogon, the pwdLastSet parameter is set to 0 and the PasswordExpired parameter to true. So we can display the users by one of these values.
Get-ADUser -Filter {pwdLastSet -eq 0} -Properties pwdLastSet | FT Name
To display by the PasswordExpired attribute, the following command should work, but in practice it doesn't filter only the true values for me. So I worked around it with the second command, which puts the true values at the beginning of the list.
Get-ADUser -Filter {PasswordExpired -eq $true} -Properties PasswordExpired | FT Name, PasswordExpired
Get-ADUser -Filter * -Properties PasswordExpired | Sort-Object PasswordExpired -Descending | FT name,PasswordExpired -AutoSize
List of disabled user accounts
Two options using different commands.
Get-ADUser -Filter {Enabled -eq $false} | FT name
Search-ADAccount -AccountDisabled -UsersOnly | Sort-Object Name | FT Name,DistinguishedName -AutoSize
List of locked user accounts
Search-ADAccount -LockedOut -UsersOnly | Sort-Object Name | FT Name,DistinguishedName -AutoSize
List of users who haven't logged in for the last 30 days
Search-ADAccount -AccountInactive -TimeSpan "30" -UsersOnly | Sort-Object LastLogonDate | FT Name,LastLogonDate,Enabled,LockedOut,PasswordExpired,DistinguishedName -AutoSize
Groups (group)
List of groups a user is a member of
Get-ADPrincipalGroupMembership -Identity bouska
Adding a user to a group
Add-ADPrincipalGroupMembership -Identity bouska -MemberOf 'G Some group'
List of users in a group
Get-ADGroupMember -Identity 'group 1' | FT name
List of users and the number of groups they are members of
Get-ADUser -Filter * -SearchBase "OU=firm,DC=firm,DC=local" -ResultPageSize 10 | ForEach-Object {
$groupc = (Get-ADPrincipalGroupMembership $_.SamAccountName | Measure-Object).Count
Write-Host $_.SamAccountName $groupc
}
List of groups based on a filter and list their members
Get-ADGroup -Filter { name -like "Group *" } | ForEach-Object { $_.SamAccountName
Get-ADGroupMember $_.SamAccountName | ForEach-Object { Write-Host " " $_.name }
}
Computers (computer account) - listing accounts and values
Computers with Windows 7 OS
Get-ADComputer -Filter {OperatingSystem -like "Windows 7*"} -Properties OperatingSystem, CanonicalName, whenCreated | Sort-Object Name | FT Name, OperatingSystem, CanonicalName, whenCreated -AutoSize
Computers with disabled account
Search-ADAccount -ComputersOnly -AccountDisabled | Sort-Object Name | FT Name,DistinguishedName,LastLogonDate -AutoSize
Computers that haven't logged in for a long time
We can either use how many days they haven't logged in, using TimeSpan, or since when they haven't logged in, using DateTime. But in both cases, it seems that the date doesn't quite match, and records from 14 days ago are displayed.
Added. This situation is a bit more complicated, and I described it in detail in the article Powershell - last computer or user login.
Search-ADAccount -ComputersOnly -AccountInactive -TimeSpan "30" | Sort-Object LastLogonDate | FT Name,LastLogonDate,Enabled,LockedOut -AutoSize
Search-ADAccount -ComputersOnly -AccountInactive -DateTime "1.11.2010" | Sort-Object LastLogonDate | FT Name,LastLogonDate,Enabled,LockedOut -AutoSize
In some cases, we may need to display other values, so an alternative using Get-ADComputer and a filter may be useful.
$logonDate = New-Object System.DateTime(2010,9,19)
Get-ADComputer -Filter { lastLogon -le $logonDate } | FT
Get-ADComputer -Filter { lastLogon -le $logonDate } -Properties LastLogonTimeStamp, OperatingSystem | Select-Object Name, DistinguishedName , OperatingSystem, LastLogonTimeStamp | Sort-Object Name
Computers that haven't changed their password for a long time
Computers that last changed their password 45 days ago. Computers in the domain must change their password regularly (default is every 30 days), if they don't, it means they are inactive.
$lastSetdate = [DateTime]::Now - [TimeSpan]::Parse("45")
Get-ADComputer -Filter {PasswordLastSet -le $lastSetdate} -Properties passwordLastSet -ResultSetSize $null | FT samaccountname,DistinguishedName,PasswordLastSet
Fungovat bude ovsem jenom lidem se zapnutou sluzbou Active Directory Web Services, jinac maji smolika stejne jako ja :-(
Dobrý den, pane Bouška měl bych dotaz, jak je možné najít uživatele dle jeho mobilního čísla v AD?
Děkuji.
respond to [2]Vláďa: Nějak jsem tenhle jednoduchý dotaz přehlédl, tak dodatečně. Třeba:
Get-ADUser -Filter { mobile -eq "+420123456789" }
Zdravím po zadání:
Get-ADGroup -Filter { name -like "Group *" } | ForEach-Object { $_.SamAccountName Get-ADGroupMember $_.SamAccountName | ForEach-Object { Write-Host " " $_.name }}
se vypíše:
Unexpected token 'Get-ADGroupMember' in expression or statement.
At line:1 char:83
Unexpected token '_' in expression or statement.
At line:1 char:101
Unexpected token '.SamAccountName' in expression or statement.
At line:1 char:103
An empty pipe element is not allowed.
At line:1 char:119
Missing closing '}' in statement block.
At line:1 char:165
Můžete poradit, kde je chyba?
respond to [4]roman: Zadejte to na řádky, jak je uvedeno v článku. Tzn. Get-ADGroupMember musí začínat na novém řádku.
Mezi .count a write-host ti chybí středník.
;-)
respond to [6]roman: Nechybí. Jako oddělovač se může použít středník stejně jako nový řádek. Ale v určitých detailech se liší.
Aha, jasně, omlouvám se...
U Výpis skupin dle filtru a seznam jejich členů mi to vypíše jenom
Group Policy Creator Owners
Administrator
a nic víc?... dají se z toho vymačkat všechny skupiny?
respond to [9]roman: Proč se to asi jmenuje "dle filtru"? Stačí upravit filtr, teď je tam "Group *", může se dát "*" pro vše.
Kamaráde, ty jsi poklad! ;-)
Díky ti moc a nezlob se za "blbý" dotazy. Dělám s tím první den a taky díky tobě to klaplo!
Zdravím, je možné nějakým příkazem v PS změnit vybrané, nebo všechny uživatele z Administrátorů na PowerUsery, tedy změnit jejich členství u doménového účtu?
Děkuji
Dobry den,
marne se snazim zmenit heslo existujícímu uzivakovi. Prikaz Set-ADAccountPassword -Identity uzivatelskejmeno -OldPassword (ConvertTo-SecureString -AsPlainText "textova_hodnota_stareho_hesla" -Force) -NewPassword (ConvertTo-SecureString -AsPlainText "textova_hodnota_noveho_hesla" -Force)
vraci chybu o neodpovidajicim heslu (to ale odpovida).
Nemate někdo třeba lepsi napad kudy na to?
Dik a dik i za clanky!
respond to [13]Hafajs:
Tak si odpovim sam :) spravne zneni je:
Import-Module ActiveDirectory
$pass= convertto-securestring -asplaintext -force -string "NoveHeslo123"
Set-ADAccountPassword bfu.tester -NewPassword $pass
A diky za reseni patri F. Wofrkovi ;-)
Ahoj,
máš super forum, hlavně ta část s power shell, jen mi tady chybí příklad: vypsání všech group, OU, v AD popř uživatelských účtů. Pokud by si mohl doplnit bylo by to super.
S pozdravem OD
Dobrý den,
existuje prosím nějaký příkaz, který zjistí, ke kteremu DC je aktuálně uživatel přiřazen? Pokud si totiž někdo zamkne účet a já ho potřebuji odemknou musím projet u nás např 9 DC než zjistím, kde je a až pak ho můžu odemknout.. Vím, že příkazem "Set lo" mi zobrazí na kterém jsem já, ale pokud mám zamčený účet tak to nezjistím..
Dobrý den,
nemohu přijít na to, jak odfiltrovat určitý kontainery, na příkazu zjištění počítačů s OS Windows 7. Ten příkaz mi ukáže celý AD na síti
respond to [17]Petan: Get-ADComputer má atribut -SearchBase pro hledání v rámci jednoho OU, ale odfiltrování některých je složité.
respond to [16]Lu2: Musím říci, že nevím.
Sám jsem to nikdy nepotřeboval. Když chci odemknout účet, tak vím v jaké Site je uživatel a jaké jsou tam DC. Na libovolném mohu odemknout účet, protože probíhá real time replikace.
Dobrý den, jaký je správný postup pro změnu computername vzdáleného PC na síti v AD pomocí PS. Děkuji
Dobrý den potřeboval bych poradit jestli je možné: Vypsat jména počítačů v doméně a který uživatel je k nim přihlášen nebo byl naposledy přihlášen.
Asi takto:
CanonicalName Name_computer Name_User LastLogonDate
Domena.cz/Kontejner/Computers/Ekonomicke/Ekonom/PC_03 PC_03 Dostálek Aleš 23.11.2017 11:41
Domena.cz/Kontejnet/Computers/Ekonomicke/Ucetni/PC_08 PC_08 Zemanová JIndra 01.02.2020 12:05
Děkuji
respond to [21]Pavel: Myslím, že to je velmi komplikované. Protože informaci, že se nějaký uživatelský účet autentizoval na nějakém počítači, máme pouze v security logu.
To jsem popisoval www.samuraj-cz.com/clanek/auditovani-bezpecnostnich-udalosti-windows-v-domene/
V dobách AVG Admin jsem s úspěcem vyžíval okně správce byl sloupec s názvem PC a naposledy přihlášeným uživatelem samozřejmě i další údaje o stavu antiviru a podobně.
Teď by se hodilo na doménových PC s občas střídají uživatelé.
:-(
Dobrý den,
Chci se zeptat jestli je možné udělat script v PowerShell, který by mi přejmenoval více uživatelů v Active Directory a změnil jim ten user logon name do formátu příjmení + 2 první písmena ze jména (momentálně jsou pojmenováni ve formě jméno.příjmení) a aby byl zachován email, tak to stávající jméno.příjmení by se hodilo do Attribute editoru do proxyAddresses ve formě SMTP:jméno.příjmení@doména.cz
Děkuji