{"id":5501,"date":"2015-06-17T00:01:00","date_gmt":"2015-06-17T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2015\/06\/17\/powershell-and-the-active-directory-schema-part-2\/"},"modified":"2019-02-18T09:47:24","modified_gmt":"2019-02-18T16:47:24","slug":"powershell-and-the-active-directory-schema-part-2","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/powershell-and-the-active-directory-schema-part-2\/","title":{"rendered":"PowerShell and the Active Directory Schema: Part 2"},"content":{"rendered":"<p><b style=\"font-size:12px\">Summary<\/b><span style=\"font-size:12px\">: Guest blogger, Andy Schneider, continues his discussion about extending the Active Directory schema.<\/span><\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. Welcome back guest blogger, <a href=\"https:\/\/devblogs.microsoft.com\/scripting\/tag\/andy-schneider\/\">Andy Schneider<\/a>, for Part 2 of his series. If you missed yesterday&#039;s post, see <a href=\"https:\/\/devblogs.microsoft.com\/scripting\/powershell-and-the-active-directory-schema\/\">PowerShell and the Active Directory Schema: Part 1<\/a>.<\/p>\n<p>Yesterday, we looked at what the Active Directory schema is and how to access details of the schema by using Windows PowerShell. In this post, we are going to look at how we can look at the schema, and also update the schema. If you didn&rsquo;t get a chance to read <a href=\"http:\/\/windowsitpro.com\/windows\/extending-active-directory-schema\" target=\"_blank\">Extending the Active Directory Schema<\/a> by Brian Desmond, I highly suggest you read through it to gain an understanding of the ramifications of schema extensions and how to properly plan for them.<\/p>\n<p>Yesterday, I left you with the following lines of code which would give us all kinds of information about the schema objects we have in Active Directory:<\/p>\n<p style=\"margin-left:30px\">$schemaPath = (Get-ADRootDSE).schemaNamingContext<\/p>\n<p style=\"margin-left:30px\">Get-ADObject -filter * -SearchBase $schemaPath -Properties * | where Name -like &quot;user&quot;<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/HSG-6-17-15-1.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/HSG-6-17-15-1.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>The question now is, &ldquo;Which ones do we care about if we want to add our own schema extensions to the user class?&rdquo;<\/p>\n<p>The way I went about this was to start looking at how schema extensions are typically done. More often than not, extensions are implemented using the <a href=\"http:\/\/en.wikipedia.org\/wiki\/LDAP_Data_Interchange_Format\" target=\"_blank\">LDAP Data Interchange Format<\/a>, also known as LDIF. There is a tool in Windows called LDIFDE.exe that you can use to import and export data. LDIFDE.exe can also be used to add attributes and classes to the Active Directory schema.<\/p>\n<p>In addition to examining LDIF files, I also went through the manual process of using the schema management tools to see what kinds of input go into the GUI. Following is a screenshot of that menu.<\/p>\n<p><b>&nbsp; &nbsp;Note<\/b> You have to register a DLL to be able to get the Schema Management MMC. You can do this with the <br \/>&nbsp; &nbsp;command<b>&nbsp;regsvr32 schmmgmt.dll<\/b>.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/HSG-6-17-15-2.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/HSG-6-17-15-2.png\" alt=\"Image of menu\" title=\"Image of menu\" \/><\/a><\/p>\n<p>By looking through a variety of LDIF file examples and the GUI tool, we can figure out what we need to supply when we create new attributes. Here is a short list:<\/p>\n<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td width=\"174\" valign=\"top\">\n<p><b>Attribute<\/b><\/p>\n<\/td>\n<td width=\"450\" valign=\"top\">\n<p><b>Description<\/b><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"174\" valign=\"top\">\n<p>Name<\/p>\n<\/td>\n<td width=\"450\" valign=\"top\">\n<p>Name of the attribute<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"174\" valign=\"top\">\n<p>lDAPDisplayName<\/p>\n<\/td>\n<td width=\"450\" valign=\"top\">\n<p>LDAP display name<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"174\" valign=\"top\">\n<p>attributeID<\/p>\n<\/td>\n<td width=\"450\" valign=\"top\">\n<p><a href=\"http:\/\/en.wikipedia.org\/wiki\/Object_identifier\" target=\"_blank\">Unique Object Identifier<\/a>, known as an OID<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"174\" valign=\"top\">\n<p>oMSyntax<\/p>\n<\/td>\n<td width=\"450\" valign=\"top\">\n<p>Determines type of data stored in the attribute (int, string, bool).&nbsp;<br \/>For reference, see <a href=\"https:\/\/technet.microsoft.com\/en-us\/library\/cc961740.aspx\" target=\"_blank\">Syntaxes<\/a>.<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"174\" valign=\"top\">\n<p>isSingleValued<\/p>\n<\/td>\n<td width=\"450\" valign=\"top\">\n<p>True or False. Attribute may have more than one value <br \/> (for example, proxyAddresses)<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td width=\"174\" valign=\"top\">\n<p>adminDescription<\/p>\n<\/td>\n<td width=\"450\" valign=\"top\">\n<p>Description of the attribute<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The one slightly tricky attribute that we need to worry about is <b>attributeID<\/b>. This needs to be a unique OID. For production, you really should register for a Private Enterprise Number with IANA. You can do this <a href=\"http:\/\/pen.iana.org\/pen\/PenApplication.page\">here<\/a>.<\/p>\n<p>However, for development purposes, we can use the following code to generate an OID:<\/p>\n<p style=\"margin-left:30px\">Function New-AttributeID {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $Prefix=&quot;1.2.840.113556.1.8000.2554&quot;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $GUID=[System.Guid]::NewGuid().ToString()<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $Parts=@()<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $Parts+=[UInt64]::Parse($guid.SubString(0,4),&quot;AllowHexSpecifier&quot;)<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $Parts+=[UInt64]::Parse($guid.SubString(4,4),&quot;AllowHexSpecifier&quot;)<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $Parts+=[UInt64]::Parse($guid.SubString(9,4),&quot;AllowHexSpecifier&quot;)<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $Parts+=[UInt64]::Parse($guid.SubString(14,4),&quot;AllowHexSpecifier&quot;)<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $Parts+=[UInt64]::Parse($guid.SubString(19,4),&quot;AllowHexSpecifier&quot;)<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $Parts+=[UInt64]::Parse($guid.SubString(24,6),&quot;AllowHexSpecifier&quot;)<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $Parts+=[UInt64]::Parse($guid.SubString(30,6),&quot;AllowHexSpecifier&quot;)<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $oid=[String]::Format(&quot;{0}.{1}.{2}.{3}.{4}.{5}.{6}.{7}&quot;,$prefix,$Parts[0],<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $Parts[1],$Parts[2],$Parts[3],$Parts[4],$Parts[5],$Parts[6])<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;$oid<\/p>\n<p style=\"margin-left:30px\">}<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/HSG-6-17-15-3.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/HSG-6-17-15-3.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>For this demonstration, we are going to add a new attribute to the user class called <b>asFavoriteColor<\/b>. I am using the &ldquo;as&rdquo; prefix simply to identify this attribute. You can use your company&rsquo;s initials or some other way to distinguish your custom extensions from other attributes. To create a new attribute, we are going to use the <b>New-ADObject<\/b> cmdlet.<\/p>\n<p>The path is going to be in the <b>schemaNamingContext<\/b> container, which we already have. We have also seen that schema attribute objects are of the type <b>attributeSchema<\/b>. New schema class objects are of the type <b>classSchema<\/b>.<\/p>\n<p>The only thing that remains are some of these properties that are unique to schema objects. We will need to store these in a hash table and pass them in via the <b>&ndash;OtherAttributes<\/b> parameter:<\/p>\n<p style=\"margin-left:30px\">$schemaPath = (Get-ADRootDSE).schemaNamingContext<\/p>\n<p style=\"margin-left:30px\">$oid = New-AttributeID<\/p>\n<p style=\"margin-left:30px\">$attributes = @{<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lDAPDisplayName = &#039;asFavoriteColor&#039;;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; attributeId = $oid;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oMSyntax = 20;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; attributeSyntax = &quot;2.5.5.4&quot;;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isSingleValued = $true;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adminDescription = &#039;favorite colors are really important&#039;;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; searchflags = 1<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"margin-left:30px\">New-ADObject -Name asFavoriteColor -Type attributeSchema -Path $schemapath -OtherAttributes $attributes<\/p>\n<p>When we create that new object, we can see our new attribute!<\/p>\n<p style=\"margin-left:30px\">get-adobject -SearchBase $schemaPath -Filter &#039;name -eq &quot;asFavoriteColor&quot;&#039;<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/HSG-6-17-15-4.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/HSG-6-17-15-4.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>However, we aren&rsquo;t quite done. We have an attribute, but it hasn&rsquo;t been attached to the user class yet. To attach an attribute to an existing class, we have to update the class to include the attribute. This was not the easiest thing to figure out.<\/p>\n<p>After looking at a few LDIF files, I finally realized that there was a property on the <b>schemaClass<\/b> objects called <b>mayContain<\/b>. This is a list of all the attributes associated with a particular class. From here, we can get the user schema object and add the new attribute to its <b>mayContain<\/b> property.<\/p>\n<p style=\"margin-left:30px\">$userSchema = get-adobject -SearchBase $schemapath -Filter &#039;name -eq &quot;user&quot;&#039;<\/p>\n<p style=\"margin-left:30px\">$userSchema | Set-ADObject -Add @{mayContain = &#039;asFavoriteColor&#039;}&nbsp;<\/p>\n<p>Now we can finally set and get the <b>asFavoriteColor<\/b> property on a user object.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0066.HSG-6-17-15-5.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0066.HSG-6-17-15-5.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>We can wrap up all this in a nice function. I set this up so I can take data from the pipeline by property names, so I can easily import a bunch of attributes from a CSV file. I also added support for <b>ShouldProcess<\/b> and set the <b>ConfirmImpact<\/b> value to High. Here is my code:<\/p>\n<p style=\"margin-left:30px\">Function New-AttributeID {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $Prefix=&quot;1.2.840.113556.1.8000.2554&quot;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $GUID=[System.Guid]::NewGuid().ToString()<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $Parts=@()<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $Parts+=[UInt64]::Parse($guid.SubString(0,4),&quot;AllowHexSpecifier&quot;)<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $Parts+=[UInt64]::Parse($guid.SubString(4,4),&quot;AllowHexSpecifier&quot;)<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $Parts+=[UInt64]::Parse($guid.SubString(9,4),&quot;AllowHexSpecifier&quot;)<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $Parts+=[UInt64]::Parse($guid.SubString(14,4),&quot;AllowHexSpecifier&quot;)<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $Parts+=[UInt64]::Parse($guid.SubString(19,4),&quot;AllowHexSpecifier&quot;)<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $Parts+=[UInt64]::Parse($guid.SubString(24,6),&quot;AllowHexSpecifier&quot;)<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $Parts+=[UInt64]::Parse($guid.SubString(30,6),&quot;AllowHexSpecifier&quot;)<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $AttributeID=[String]::Format(&quot;{0}.{1}.{2}.{3}.{4}.{5}.{6}.{7}&quot;,$prefix,$Parts[0],<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $Parts[1],$Parts[2],$Parts[3],$Parts[4],$Parts[5],$Parts[6])<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $oid<\/p>\n<p style=\"margin-left:30px\">}<\/p>\n<p style=\"margin-left:30px\">Function Update-Schema {<\/p>\n<p style=\"margin-left:30px\">[CmdletBinding(SupportsShouldProcess,ConfirmImpact=&#039;High&#039;)]<\/p>\n<p style=\"margin-left:30px\">param(<\/p>\n<p style=\"margin-left:30px\">[Parameter(Mandatory,ValueFromPipelinebyPropertyName)]<\/p>\n<p style=\"margin-left:30px\">$Name,<\/p>\n<p style=\"margin-left:30px\">[Parameter(Mandatory,ValueFromPipelinebyPropertyName)]<\/p>\n<p style=\"margin-left:30px\">[Alias(&#039;DisplayName&#039;)]<\/p>\n<p style=\"margin-left:30px\">$LDAPDisplayName,<\/p>\n<p style=\"margin-left:30px\">[Parameter(Mandatory,ValueFromPipelinebyPropertyName)]<\/p>\n<p style=\"margin-left:30px\">[Alias(&#039;Description&#039;)]<\/p>\n<p style=\"margin-left:30px\">$AdminDescription,<\/p>\n<p style=\"margin-left:30px\">[Parameter(Mandatory,ValueFromPipelinebyPropertyName)]<\/p>\n<p style=\"margin-left:30px\">[Alias(&#039;SingleValued&#039;)]<\/p>\n<p style=\"margin-left:30px\">$IsSingleValued,<\/p>\n<p style=\"margin-left:30px\">[Parameter(ValueFromPipelinebyPropertyName)]<\/p>\n<p style=\"margin-left:30px\">[Alias(&#039;OID&#039;)]<\/p>\n<p style=\"margin-left:30px\">$AttributeID = (New-OID)<\/p>\n<p style=\"margin-left:30px\">)<\/p>\n<p style=\"margin-left:30px\">BEGIN {}<\/p>\n<p style=\"margin-left:30px\">PROCESS {<\/p>\n<p style=\"margin-left:30px\">&nbsp; $schemaPath = (Get-ADRootDSE).schemaNamingContext&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"margin-left:30px\">&nbsp; $type = &#039;attributeSchema&#039;<\/p>\n<p style=\"margin-left:30px\">&nbsp; switch ($isSingleValued)<\/p>\n<p style=\"margin-left:30px\">&nbsp; {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp; &#039;True&#039;&nbsp; {$IsSingleValued = $true}<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp; &#039;False&#039; {$IsSingleValued = $false}<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp; default {$IsSingleValued = $true}<\/p>\n<p style=\"margin-left:30px\">&nbsp; }<\/p>\n<p style=\"margin-left:30px\">&nbsp; $attributes = @{<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lDAPDisplayName = $Name;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; attributeId = $AttributeID;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oMSyntax = 20;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; attributeSyntax = &quot;2.5.5.4&quot;;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isSingleValued = $IsSingleValued;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; adminDescription = $AdminDescription;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; searchflags = 1<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $ConfirmationMessage = &quot;$schemaPath. This cannot be undone&quot;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $Caption = &#039;Updating Active Directory Schema&#039;&nbsp;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; if ($PSCmdlet.ShouldProcess($ConfirmationMessage,$Caption))<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; {<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; New-ADObject -Name $Name -Type $type -Path $schemapath -OtherAttributes $attributes<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $userSchema = get-adobject -SearchBase $schemapath -Filter &#039;name -eq &quot;user&quot;&#039;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $userSchema | Set-ADObject -Add @{mayContain = $Name}<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"margin-left:30px\">}<\/p>\n<p style=\"margin-left:30px\">END {}<\/p>\n<p style=\"margin-left:30px\">}<\/p>\n<p>You can download this code from GitHub: <a href=\"https:\/\/gist.github.com\/AndyPowerShell\/2b9521e1db5d9a582d23#file-update-schema-ps1\" target=\"_blank\">PowerShell to Udpate Active Directory Schema<\/a>.<\/p>\n<p>This purpose of this series and code is to show you the basics of how to use native Windows PowerShell to extend the Active Directory schema. I would like to reiterate that any schema modifications should be well thought out and planned for. There are many more attributes that can be used and that could be useful. You can use this code as a basic framework for updating the schema with your company&rsquo;s requirements and standards.<\/p>\n<p>~Andy<\/p>\n<p>Thank you Andy. This is some awesome material.<\/p>\n<p>I 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=\"mailto: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.<\/p>\n<p><b>Ed Wilson, Microsoft Scripting Guy<\/b><span style=\"font-size:12px\">&nbsp;<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Guest blogger, Andy Schneider, continues his discussion about extending the Active Directory schema. Microsoft Scripting Guy, Ed Wilson, is here. Welcome back guest blogger, Andy Schneider, for Part 2 of his series. If you missed yesterday&#039;s post, see PowerShell and the Active Directory Schema: Part 1. Yesterday, we looked at what the Active Directory [&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,156,56,3,549,45],"class_list":["post-5501","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-active-directory","tag-andy-schneider","tag-guest-blogger","tag-scripting-guy","tag-series","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Guest blogger, Andy Schneider, continues his discussion about extending the Active Directory schema. Microsoft Scripting Guy, Ed Wilson, is here. Welcome back guest blogger, Andy Schneider, for Part 2 of his series. If you missed yesterday&#039;s post, see PowerShell and the Active Directory Schema: Part 1. Yesterday, we looked at what the Active Directory [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/5501","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=5501"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/5501\/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=5501"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=5501"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=5501"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}