{"id":2633,"date":"2013-11-01T00:01:00","date_gmt":"2013-11-01T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2013\/11\/01\/building-a-demo-active-directory-part-5\/"},"modified":"2013-11-01T00:01:00","modified_gmt":"2013-11-01T00:01:00","slug":"building-a-demo-active-directory-part-5","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/building-a-demo-active-directory-part-5\/","title":{"rendered":"Building a Demo Active Directory: Part 5"},"content":{"rendered":"<p align=\"left\"><strong>Summary<\/strong>: Add users to random security groups, provide random passwords, and enable accounts.<\/p>\n<p align=\"left\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" alt=\"Hey, Scripting Guy! Question\">&nbsp;Hey, Scripting Guy!<\/p>\n<p align=\"left\">I have created a bunch of users in my sample Active Directory, but I have all these security groups that I need to populate. How can I do that with Windows PowerShell?<\/p>\n<p align=\"left\">&mdash;BB<\/p>\n<p align=\"left\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" alt=\"Hey, Scripting Guy! Answer\">&nbsp;Hello BB,<\/p>\n<p align=\"left\">Honorary Scripting Guy, Sean Kearney here, filling in for our good friend, Ed.<\/p>\n<p align=\"left\">To catch up on the previous posts in this series, please read:<\/p>\n<ul>\n<li><a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2013\/10\/28\/building-a-demo-active-directory-part-1.aspx\" target=\"_blank\">Building a Demo Active Directory: Part 1<\/a><\/li>\n<li><a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2013\/10\/29\/building-a-demo-active-directory-part-2.aspx\" target=\"_blank\">Building a Demo Active Directory: Part 2<\/a><\/li>\n<li><a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2013\/10\/31\/building-a-demo-active-directory-part-2.aspx\" target=\"_blank\">Building a Demo Active Directory: Part 3<\/a><\/li>\n<li><a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2013\/10\/31\/building-a-demo-active-directory-part-4.aspx\" target=\"_blank\">Building a Demo Active Directory: Part 4<\/a><\/li>\n<\/ul>\n<p align=\"left\">We&rsquo;re entering in the final stretch! Populating the security groups. This is actually easier than you can imagine.<\/p>\n<p align=\"left\">Previously, we built security groups where the names were based on the city and division, and they were targeted at those specific entries in the tree. That means if a user was in the &ldquo;Ottawa\/HR&rdquo; organizational unit, the security group name was called &ldquo;Ottawa-HR&rdquo;.<\/p>\n<p align=\"left\">We can make a minor insertion into the script. We&rsquo;ll leverage the already chosen random city and division when we populate a user and generate the security group name. We&rsquo;ll use the function that we created earlier, <strong>GET-GROUPINFO<\/strong>, to meet that need.<\/p>\n<p style=\"padding-left: 30px\" align=\"left\"># Pick a Random City<\/p>\n<p style=\"padding-left: 30px\" align=\"left\">$City=GET-RANDOM $Cityou<\/p>\n<p style=\"padding-left: 30px\" align=\"left\"># Pick a Random Division<\/p>\n<p style=\"padding-left: 30px\" align=\"left\">$Division=GET-RANDOM $DivisionOU<\/p>\n<p style=\"padding-left: 30px\" align=\"left\">$GroupName=(GET-GroupInfo &ndash;City $City &ndash;Division $Division).Name<\/p>\n<p align=\"left\">Then all we need to do is add the user to the group. We do this with the <strong>Add-ADGroupMember<\/strong> cmdlet:<\/p>\n<p style=\"padding-left: 30px\" align=\"left\">ADD-ADGroupMember $Groupname &ndash;Members $Sam<\/p>\n<p align=\"left\">But there are two other pieces that we should remember:<\/p>\n<ul>\n<li>These accounts are not enabled<\/li>\n<li>No passwords have been assigned<\/li>\n<\/ul>\n<p align=\"left\">If the accounts have no passwords, you won&rsquo;t be able to enable them. So what we should do when we create the user is include some type of password generation function.<\/p>\n<p align=\"left\">There are so many solutions to generating a random password in Windows PowerShell. I could go on for days. For this, I adapted a simple and effective idea my friend and fellow Windows PowerShell MVP, <a href=\"http:\/\/dmitrysotnikov.wordpress.com\/2007\/07\/18\/generate-random-password-with-powershell\/\">Dmitry Sotnikov<\/a>, wrote to meet this need.<\/p>\n<p align=\"left\">We use <strong>Convert-ToSecureString<\/strong> because the <strong>New-ADUser<\/strong> cmdlet is expecting a secure string for the password:<\/p>\n<p style=\"padding-left: 30px\" align=\"left\">Function GeneratePassword<\/p>\n<p style=\"padding-left: 30px\" align=\"left\">{<\/p>\n<p style=\"padding-left: 30px\" align=\"left\"># How many Characters Minimum?<\/p>\n<p style=\"padding-left: 30px\" align=\"left\">$Length=15<\/p>\n<p style=\"padding-left: 30px\" align=\"left\"># Create a password choosing everything from Character 34 to 127<\/p>\n<p style=\"padding-left: 30px\" align=\"left\">1..$Length | foreach{ $Password+=([char]((Get-Random 93)+34))}<\/p>\n<p style=\"padding-left: 30px\" align=\"left\"># Convert to a Secure String<\/p>\n<p style=\"padding-left: 30px\" align=\"left\">$Password=Convertto-SecureString $Password -asplaintext -force<\/p>\n<p style=\"padding-left: 30px\" align=\"left\">Return $Password<\/p>\n<p style=\"padding-left: 30px\" align=\"left\">}<\/p>\n<p align=\"left\">Granted, this will generate some truly unpronounceable passwords, and it may reflect the words they show in comic strips when cartoon characters let forth &ldquo;magic words.&rdquo; But for our demo environment , it will be fine. Of course afterwards, we&rsquo;ll need to ensure that the accounts are enabled in Active Directory. For this we can use the <strong>Enable-ADAccount<\/strong> cmdlet, which would look like this when used for SAM account ID &ldquo;jsmith&rdquo;:<\/p>\n<p style=\"padding-left: 30px\" align=\"left\">ENABLE-ADACCOUNT jsmith<\/p>\n<p align=\"left\">If the password is created and enabled and it passes complexity rules, the account will show as <strong>Active<\/strong>. Failing that, Windows PowerShell will show an error message that indicates your password isn&rsquo;t up to snuff.<\/p>\n<p align=\"left\">So with all the pieces put into action, our final script will look like this:<\/p>\n<p style=\"padding-left: 30px\">Import-module ActiveDirectory<\/p>\n<p style=\"padding-left: 30px\"># Crude Random Password Generator&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Function GeneratePassword<\/p>\n<p style=\"padding-left: 30px\">{<\/p>\n<p style=\"padding-left: 30px\"># How many Characters Minimum?<\/p>\n<p style=\"padding-left: 30px\">$Length=15<\/p>\n<p style=\"padding-left: 30px\"># Create a password choosing everying from Character 34 to 127<\/p>\n<p style=\"padding-left: 30px\">1..$Length | foreach{ $Password+=([char]((Get-Random 93)+34))}<\/p>\n<p style=\"padding-left: 30px\"># Convert to a Secure String<\/p>\n<p style=\"padding-left: 30px\">$Password=Convertto-SecureString $Password -asplaintext -force<\/p>\n<p style=\"padding-left: 30px\">Return $Password<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\">Function GET-GroupInfo()<\/p>\n<p style=\"padding-left: 30px\">{<\/p>\n<p style=\"padding-left: 30px\">Param(<\/p>\n<p style=\"padding-left: 30px\">$City,<\/p>\n<p style=\"padding-left: 30px\">$Division<\/p>\n<p style=\"padding-left: 30px\">)<\/p>\n<p style=\"padding-left: 30px\">$GroupName=$City.replace(&#8221; &#8220;,&#8221;&#8221;)+&#8221;-&#8220;+$Division.replace(&#8221; &#8220;,&#8221;&#8221;)<\/p>\n<p style=\"padding-left: 30px\">$GroupDescription=&#8221;$Division in $City Access Group&#8221;<\/p>\n<p style=\"padding-left: 30px\"># Return the Results (This is a feature new to version 3)<\/p>\n<p style=\"padding-left: 30px\">[pscustomobject]@{Name=$Groupname;Description=$GroupDescription}<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\"># Define OU at Base of AD for Offices<\/p>\n<p style=\"padding-left: 30px\">$BaseOU=&#8221;Offices&#8221;<\/p>\n<p style=\"padding-left: 30px\"># Provide List of Office Names<\/p>\n<p style=\"padding-left: 30px\">$CityOU=&ldquo;Tokyo&rdquo;,&rdquo;Redmond&rdquo;,&rdquo;Ottawa&rdquo;,&rdquo;Madrid&rdquo;,&rdquo;New Orleans&rdquo;,&rdquo;Queensland&rdquo;<\/p>\n<p style=\"padding-left: 30px\"># Provide List of Divisions Per Office<\/p>\n<p style=\"padding-left: 30px\">$DivisionOU=&#8221;Sales&#8221;,&#8221;Marketing&#8221;,&#8221;HR&#8221;,&#8221;Finance&#8221;<\/p>\n<p style=\"padding-left: 30px\"># DistinguishedName of Domain Root<\/p>\n<p style=\"padding-left: 30px\">$Domain=&#8221;DC=Contoso,DC=Local&#8221;<\/p>\n<p style=\"padding-left: 30px\"># Whatever the name of the $BaseOU Combined with Domain<\/p>\n<p style=\"padding-left: 30px\">$CompanyPath=&#8221;OU=$BaseOU,&#8221;+$Domain<\/p>\n<p style=\"padding-left: 30px\"># UPN Extension to the Domain<\/p>\n<p style=\"padding-left: 30px\">$UPN=&#8221;@contoso.local&#8221;<\/p>\n<p style=\"padding-left: 30px\"># Create BaseOU for Offices<\/p>\n<p style=\"padding-left: 30px\">NEW-ADOrganizationalUnit -name $BaseOU -path $Domain<\/p>\n<p style=\"padding-left: 30px\"># Gather through list of Cities<\/p>\n<p style=\"padding-left: 30px\">Foreach ($City in $CityOU)&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; # Create OU for City<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; NEW-ADOrganizationalUnit -path $CompanyPath -name $City<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; # Gather through list of Divisions<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; Foreach($Division in $DivisionOU)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; {<\/p>\n<p style=\"padding-left: 30px\">&nbsp;# Create Division within City<\/p>\n<p style=\"padding-left: 30px\">&nbsp;NEW-ADOrganizationalUnit -path &#8220;OU=$City,$CompanyPath&#8221; -name $Division<\/p>\n<p style=\"padding-left: 30px\">&nbsp;# Create Group within Division and Description<\/p>\n<p style=\"padding-left: 30px\">$Groupdata=GET-Groupinfo &ndash;City $City &ndash;Division $Division<\/p>\n<p style=\"padding-left: 30px\">$GroupName=$Groupdate.Name<\/p>\n<p style=\"padding-left: 30px\">$GroupDescription=$Groupdata.Description<\/p>\n<p style=\"padding-left: 30px\">NEW-ADGroup -name $GroupName -GroupScope Global -Description $GroupDescription -Path &#8220;OU=$Division,OU=$City,$CompanyPath&#8221;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"padding-left: 30px\">}<\/p>\n<p style=\"padding-left: 30px\"># Pull together list of CSV raw data supplied from Generator<\/p>\n<p style=\"padding-left: 30px\">#&nbsp;<\/p>\n<p style=\"padding-left: 30px\">$Names=IMPORT-CSV C:Scriptsamplenames.csv<\/p>\n<p style=\"padding-left: 30px\"># Generate 150 Random Users from pulled Raw data<\/p>\n<p style=\"padding-left: 30px\">For ($x=0;$x -lt 150;$x++)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;# Pick a Random First and Last Name<\/p>\n<p style=\"padding-left: 30px\">&nbsp;$Firstname=GET-Random $Names.Firstname<\/p>\n<p style=\"padding-left: 30px\">&nbsp;$Lastname=GET-Random $Names.Lastname<\/p>\n<p style=\"padding-left: 30px\">&nbsp;$Displayname=$Lastname+&rdquo;, &ldquo;+$Firstname<\/p>\n<p style=\"padding-left: 30px\">&nbsp;{<\/p>\n<p style=\"padding-left: 30px\">&nbsp;# Pick a Random City<\/p>\n<p style=\"padding-left: 30px\">&nbsp;$City=GET-RANDOM $Cityou<\/p>\n<p style=\"padding-left: 30px\">&nbsp;# Pick a Random Division<\/p>\n<p style=\"padding-left: 30px\">&nbsp;$Division=GET-RANDOM $DivisionOU<\/p>\n<p style=\"padding-left: 30px\">&nbsp;$LoginID=$Firstname.substring(0,1)+$Lastname<\/p>\n<p style=\"padding-left: 30px\">&nbsp;$UserPN=$LoginID+$UPN<\/p>\n<p style=\"padding-left: 30px\">&nbsp;$Sam=$LoginID.padright(20).substring(0,20).trim()<\/p>\n<p style=\"padding-left: 30px\">&nbsp;# Define their path in Active Directory<\/p>\n<p style=\"padding-left: 30px\">&nbsp;$ADPath=&#8221;OU=$Division,OU=$City,$CompanyPath&#8221;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;# Create the user in Active Directory<\/p>\n<p style=\"padding-left: 30px\">&nbsp;New-ADUser -GivenName $Givenname -Surname $Surname -DisplayName $Displayname -UserPrincipalName $UserPN -Division $Division -City $City -Path $ADPath -name $Displayname -SamAccountName $Sam &ndash;userpassword (GENERATEPASSWORD)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;# Add User to appropriate Security Group<\/p>\n<p style=\"padding-left: 30px\">&nbsp;$Groupname=(GET-GroupInfo &ndash;city $City &ndash;division $Division).Name<\/p>\n<p style=\"padding-left: 30px\">&nbsp;ADD-ADGroupmember $Groupname &ndash;members $Sam<\/p>\n<p style=\"padding-left: 30px\">&nbsp;# Enable the account for access<\/p>\n<p style=\"padding-left: 30px\">&nbsp;ENABLE-ADAccount $Sam<\/p>\n<p style=\"padding-left: 30px\">&nbsp;}<\/p>\n<p style=\"padding-left: 30px\">}&nbsp;<\/p>\n<p align=\"left\">Save this all as a script called, say, NEWDEMO.PS1, and with very little time you can generate your very own customized Active Directory structure that can contain 1000&rsquo;s of users. All without clicking away on that poor little mouse.<\/p>\n<p align=\"left\">You could customize this even further by outputting the names, generating some random computer objects, or even possibly creating more security groups. You are only limited by your imagination.<\/p>\n<p align=\"left\">Check back tomorrow! The weekend is here, and I sense far more Windows PowerShell coolness in the midst!<\/p>\n<p align=\"left\">I invite you to follow the Scripting Guys 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 <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.<\/p>\n<p align=\"left\"><strong>Sean Kearney<\/strong>, Honorary Scripting Guy and Windows PowerShell MVP<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Add users to random security groups, provide random passwords, and enable accounts. &nbsp;Hey, Scripting Guy! I have created a bunch of users in my sample Active Directory, but I have all these security groups that I need to populate. How can I do that with Windows PowerShell? &mdash;BB &nbsp;Hello BB, Honorary Scripting Guy, Sean [&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,56,3,154,45],"class_list":["post-2633","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-active-directory","tag-guest-blogger","tag-scripting-guy","tag-sean-kearney","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Add users to random security groups, provide random passwords, and enable accounts. &nbsp;Hey, Scripting Guy! I have created a bunch of users in my sample Active Directory, but I have all these security groups that I need to populate. How can I do that with Windows PowerShell? &mdash;BB &nbsp;Hello BB, Honorary Scripting Guy, Sean [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/2633","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=2633"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/2633\/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=2633"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=2633"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=2633"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}