Today something very simple, basic and hardly clever. I’m blogging about it only because I couldn’t find any resource that would help me with doing that directly from PowerShell. I tried to do that in smarter way, but so far failed. If you know a better way than this one – please don’t hesitate and share your knowledge with me (and others)
To the point: last few days I’m working on a larger script that should help AD team to fix orphaned admin accounts. While testing I needed a way to trigger SDProp at will, as described in this article.
I was using ldp.exe so far, but today I said – no more! I needed a way to do the same from PowerShell. Score so far ldp 1 : me 0…
Than I thought: I’m in the shell, right? So… instead of finding solution, I can walk around the problem, as long as there is a command line utility that can help me with that. Search results did not left me with any choice here. If you have ldif, you probably want to use ldifde.
You only have to remember to do that on PDC emulator role holder. That’s not hard to find, especially if you have ActiveDirectory module handy. Whole script:
$PDC = Get-ADDomain | select -ExpandProperty PDCEmulator Invoke-Command { $Temp = [io.path]::GetTempFileName() Set-Content -Path $Temp -Value @' dn: changetype: modify add: runProtectAdminGroupsTask runProtectAdminGroupsTask: 1 - '@ ldifde -i -f $Temp Remove-Item -Force $Temp } -ComputerName $PDC
As you can see – it’s not very complex nor pretty. But it works, and I no longer have to launch ldp.exe to push AdminCount down to my “protected” users and groups.
EDIT:
As Jaap suggested, ActiveDirectory module can be avoided as dependency: instead of calling Get-ADDomain (that may be absent on your box) you get same information using ADSI:
$NTDSPDCEmulator = ([adsi]'').fsmoroleowner[0] $PDCEmulator = ([adsi]"LDAP://$NTDSPDCEmulator").Parent $PDC = ([adsi]$PDCEmulator).DnsHostName
With that – you can run on any box that is a member of your domain.
When using the [adsi] Accelerator it is even possible to remove the dependency on the ActiveDirectory module completely. For example the next code sample will retrieve the PDC Emulator DNS Hostname:
$NTDSPDCEmulator = ([adsi]'').fsmoroleowner[0]
$PDCEmulator = ([adsi]"LDAP://$NTDSPDCEmulator").Parent
$PDCDNSName = ([adsi]$PDCEmulator).DnsHostName
This can also be shortened to a one-liner as such:
([adsi]([adsi]"LDAP://$(([adsi]'').fsmoroleowner[0])").Parent).DnsHostName
Awesome! 🙂 To be completely honest I didn’t spent too much time on looking for role owner.
In my own, virtual lab I’m sure which DC holds this role, so in reality, I was not performing this test at all, but decided it may be handy for someone else to add this test in code posted here. Will update post with your code today. With (c) and all that. 😉
I like the .Net framework way of getting the PDC emulator too:
PDCDNSName = ([System.DirectoryServices.ActiveDirectory.Domain]::GetComputerDomain()).PdcRoleOwner.Name
You don’t need ldifde to submit the modify operation!
$NTDSPDCEmulator = ([adsi]”).fsmoroleowner[0]
$PDCEmulator = ([adsi]”LDAP://$NTDSPDCEmulator”).Parent
$PDCDNSName = ([adsi]$PDCEmulator).DnsHostName
$PDCERootDSE = [adsi]”LDAP://$PDCDNSName/RootDSE”
$PDCERootDSE.Put(“runProtectAdminGroupsTask”,”1″)
$PDCERootDSE.SetInfo()
Now you can do it from anywhere without any AD specific tools at all 🙂