{"id":7991,"date":"2015-02-07T00:01:00","date_gmt":"2015-02-07T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2015\/02\/07\/weekend-scripter-use-powershell-to-delegate-administrator-of-rodcs\/"},"modified":"2019-02-18T10:30:44","modified_gmt":"2019-02-18T17:30:44","slug":"weekend-scripter-use-powershell-to-delegate-administrator-of-rodcs","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/weekend-scripter-use-powershell-to-delegate-administrator-of-rodcs\/","title":{"rendered":"Weekend Scripter: Use PowerShell to Delegate Administrator of RODCs"},"content":{"rendered":"<p><b style=\"font-size:12px\">Summary<\/b><span style=\"font-size:12px\">: Microsoft PFE, Ian Farr, discusses using Windows PowerShell to delegate administrator of RODC.<\/span>\nMicrosoft Scripting Guy, Ed Wilson, is here. Today we have Honorary Scripting Guy and Microsoft PFE, Ian Farr, back for more words of wisdom&#8230;\nWelcome to the third post in a four part series about securing and managing read-only domain controllers (RODCs). I like to think of this collection of posts as &#8220;organic&#8221;&mdash;they only became a series after the green shoots of the first two posts were already well established!\nThe first post discussed a function that analyses RODC authentication. The function reports on accounts that are authenticated by an RODC that aren&rsquo;t revealed (that is, the account password or secret is not stored on the RODC). It helps you manage your password replication policies. For the full write up, see <a href=\"http:\/\/blogs.technet.comhttps:\/\/devblogs.microsoft.com\/scripting\/use-powershell-to-work-with-rodc-accounts\/\" target=\"_blank\">Use PowerShell to Work with RODC Accounts<\/a>.\nThe second post discussed a function that checks whether a user is a member of a high-privileged group. It can be used in conjunction with the first function to see if your RODCs have authenticated high-privileged users. This helps identify and remove a potential means of compromising Active Directory. To read that post, see <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2014\/11\/15\/use-powershell-to-search-active-directory-for-high-privileged-accounts.aspx\" target=\"_blank\">Use PowerShell to Search Active Directory for High-Privileged Accounts<\/a>.\nToday&rsquo;s post discusses a function that allows you to delegate the administration of an RODC. The function adds a user or a group to the <b>ManagedBy<\/b> attribute of the computer account for the RODC. This grants the user or group members local administrative privileges on the RODC.<\/p>\n<p style=\"margin-left:30px\"><b>Note<\/b>&nbsp; Users delegated as RODC administrators should not be a member of any privileged groups in Active Directory because this negates the protections that an RODC provides. Furthermore, the accounts used for delegated administration should be &#8220;secondary logon accounts&#8221; that are used only for RODC administration. For example, they should not be accounts that are also used to log on to workstations for typical user activity, such as Internet browsing or reading email.\nHere&rsquo;s the function: <a href=\"https:\/\/gallery.technet.microsoft.com\/scriptcenter\/Set-ADRodcManagedByAttribut-57e99d99\" target=\"_blank\">Set-ADRodcManagedByAttribute<\/a>\nLet&rsquo;s take a look&hellip;\nThe function has two parameters: <strong>Rodc<\/strong> and <strong>Principle<\/strong>.\n<b>Rodc<\/b> &nbsp;This parameter determines the RODC on which the <b>ManagedBy<\/b> attribute is set. It can accept a value from the pipeline, so we can pipe a list of RODCs into the function. There&rsquo;s also some parameter validation to ensure that we are dealing with an RODC. If the domain controller object has the <b>IsReadOnly<\/b> attribute set to True, we know we have an RODC.<\/p>\n<p style=\"margin-left:30px\">[parameter(Mandatory,Position=1,ValueFromPipeline)]<\/p>\n<p style=\"margin-left:30px\">[ValidateScript({(Get-ADDomainController -Identity $_).IsReadOnly})]<\/p>\n<p style=\"margin-left:30px\">[String]$Rodc\n<b>Principal<\/b> &nbsp;This parameter defines the user or group that is added to the <b>ManagedBy<\/b> attribute. It has to be a <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa366101(v=vs.85).aspx\">DistinguishedName<\/a>. The parameter validation uses the <b>&ndash;Identity<\/b> parameter of <b>Get-ADObject<\/b>, which only accepts a distinguished name and will check whether the user or group exists in Active Directory. The <b>ManagedBy<\/b> attribute should be populated with a domain local group.<\/p>\n<p style=\"margin-left:30px\">[parameter(Mandatory,Position=2)]<\/p>\n<p style=\"margin-left:30px\">[ValidateScript({Get-ADObject -Identity $_})]<\/p>\n<p style=\"margin-left:30px\">[String]$Principal\nThe function has a <b>Begin<\/b> statement block to perform further validation before each RODC object is processed. In the following script, we check that the object supplied to the <b>Principal<\/b> parameter is a <b>User<\/b> or <b>Group<\/b> object. If it isn&rsquo;t, we <b>Break<\/b> out of the function.<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp; Begin {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #Get the supplied AD Object<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $ADObject= Get-ADObject -Identity $Principal -ErrorAction SilentlyContinue\n&nbsp;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #Check that $Principal is a user or group<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; If (($ADObject.ObjectClass -ne &#8220;user&#8221;) -and ($ADObject.ObjectClass -ne &#8220;group&#8221;)) {\n&nbsp;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #Write a message to the host<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Write-Host &#8220;$Principal is not a user or group&#8221;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Break<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } &nbsp;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;\nNext, we enter the <b>Process<\/b> statement block. We iterate through each RODC that is passed into the function and use the <b>Get-ADComputer<\/b> and <b>Set-ADObject<\/b> cmdlets to update the <b>ManagedBy<\/b> attribute. On the associated computer account object, to our user or group <b>DistinguishedName<\/b>, the <b>-Replace<\/b> parameter makes use of a hash table that references our user or group principal.<\/p>\n<p style=\"margin-left:30px\">Process {<\/p>\n<p style=\"margin-left:30px\">#Set the ManagedBy attribute<\/p>\n<p style=\"margin-left:30px\">Get-ADComputer -Identity $Rodc | Set-ADObject -Replace @{ManagedBy = $Principal}<\/p>\n<p style=\"margin-left:30px\">} &nbsp;\nHere&rsquo;s an example of how to use the function:<\/p>\n<p style=\"margin-left:30px\">Get-ADDomainController -Filter {IsReadOnly -eq $True} |<\/p>\n<p style=\"margin-left:30px\">Set-ADRodcManagedByAttribute -Principal &#8220;CN=RODC Admins,OU=Groups,DC=Fabrikam,DC=com&#8221;\nIn this command, we get all of the RODCs for the current domain and pipe them into the <b>Set-ADRodcManagedByAttribute<\/b> function. This updates the <b>ManagedBy<\/b> attribute of each corresponding computer object to the distinguished name of the <b>RODC Admins<\/b> domain local group. Of course, we could also pipe a specific list of RODCs into the function to meet a particular administrative requirement, or simply run the function by itself against a single RODC.\nAnd that&rsquo;s it. Next time out, I&rsquo;ll talk about synchronizing our delegated RODCs administrators&rsquo; passwords to their respective RODCs.\n~Ian\nThanks, Ian. Join us tomorrow when Ian returns for the final part of this series.\nI invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"http:\/\/blogs.technet.commailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.\n<b>Ed Wilson, Microsoft Scripting Guy<\/b><span style=\"font-size:12px\">&nbsp;<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Microsoft PFE, Ian Farr, discusses using Windows PowerShell to delegate administrator of RODC. Microsoft Scripting Guy, Ed Wilson, is here. Today we have Honorary Scripting Guy and Microsoft PFE, Ian Farr, back for more words of wisdom&#8230; Welcome to the third post in a four part series about securing and managing read-only domain controllers [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[7,566,56,472,3,61,45],"class_list":["post-7991","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-active-directory","tag-domain-controllers","tag-guest-blogger","tag-ian-farr","tag-scripting-guy","tag-weekend-scripter","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Microsoft PFE, Ian Farr, discusses using Windows PowerShell to delegate administrator of RODC. Microsoft Scripting Guy, Ed Wilson, is here. Today we have Honorary Scripting Guy and Microsoft PFE, Ian Farr, back for more words of wisdom&#8230; Welcome to the third post in a four part series about securing and managing read-only domain controllers [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/7991","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=7991"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/7991\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=7991"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=7991"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=7991"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}