{"id":55003,"date":"2008-10-16T11:12:00","date_gmt":"2008-10-16T11:12:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2008\/10\/16\/hey-scripting-guy-how-can-i-create-passwords-for-my-users\/"},"modified":"2008-10-16T11:12:00","modified_gmt":"2008-10-16T11:12:00","slug":"hey-scripting-guy-how-can-i-create-passwords-for-my-users","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-create-passwords-for-my-users\/","title":{"rendered":"Hey, Scripting Guy! How Can I Create Passwords for My Users?"},"content":{"rendered":"<h2><img decoding=\"async\" class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" height=\"34\" alt=\"Hey, Scripting Guy! Question\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\" \/> <\/h2>\n<p>Hey, Scripting Guy! I am trying to create a bunch of users via script, but I am having problems dealing with their passwords. I do not want to give everyone the same password, and I do not want to have to manually create a hundred passwords and store them in a file, so I am nearly at a loss. I have seen some password generator programs on the Internet, and I think I need something like that, but I would love to be able to do it in a script instead. The one I downloaded had a user interface and did not appear to be scriptable. Can you create passwords in a script using Windows PowerShell?<\/p>\n<p>&#8211; RS<\/p>\n<p><img decoding=\"async\" height=\"5\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" border=\"0\" \/><img decoding=\"async\" class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" height=\"34\" alt=\"Hey, Scripting Guy! Answer\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\" \/> <\/p>\n<p>Hi RS,<\/p>\n<p>You know, one time my dad gave me a beautiful hammer. The hammer had a forged 12-ounce head and a carved rosewood handle with a leather grip. It was the nicest tool I had ever seen. It was way too good to leave laying around in my wood working shop, so I brought it into the house. The problem is that my hammering needs in the house were always a bit limited. So, if I had a screw that needed installing, I reached for the hammer. If I had ice that needed crushing, hammer time. Need to fix the TV set, hammer. The day I decided to see if my magic hammer would be any good at breaking eggs was the day the scripting wife told me to take my hammer back to the shop.<\/p>\n<p>What&#8217;s the point of all this? Well, RS, sometimes tools are designed for a specific purpose, and while they may be great at that particular task, they are not so hot at other jobs for which they were not designed and were never intended. So while your Internet password generator may be good at creating a list of random passwords, it was probably never intended for that purpose. We could possibly use the <b>SendKeys<\/b> method from the <b>WshShell<\/b> object to operate your program. Here is an example of using <b>SendKeys<\/b> (from VBScript fame):<\/p>\n<pre class=\"codeSample\">$wshShell = New-Object -ComObject wscript.shell\n[void]$wshShell.Run(\"calc\")\n[void]$wshshell.AppActivate(\"calculator\")\nStart-Sleep -milliseconds 100\n$wshShell.SendKeys(\"1{+}2~\")\nStart-Sleep -milliseconds 100\n$wshShell.SendKeys(\"*5~\")<\/pre>\n<p>You can see that using <b>SendKeys<\/b> in Windows PowerShell works exactly the same as the way it worked in VBScript. The first thing we do is create an instance of the <b>WshShell<\/b> object. We do this by using the <b>New-Object<\/b> cmdlet. In VBScript, we would use <b>CreateObject<\/b> instead of <b>New-Object<\/b>. We need to tell <b>New-Object<\/b> that we are creating a COM object and give it the program ID. This is seen here:<\/p>\n<pre class=\"codeSample\">$wshshell = New-Object -ComObject wscript.shell<\/pre>\n<p>We then use the <b>Run<\/b> method from the <b>WshShell<\/b> object contained in the <b>$wshShell<\/b> variable to launch an instance of the Calculator program. We could have just typed <b>Calc<\/b> instead of using the <b>Run<\/b> method, but hey, we already had the <b>WshShell<\/b> object, so we may as well use it. The next thing we do is bring Calculator to the foreground so that we can work with it. There are two tricky things here. The first is that the name of the executable is <b>Calc.exe<\/b>, so we need to use <b>Calc<\/b> when using the <b>Run<\/b> method. The window title is <b>Calculator<\/b>, so we need to use that with the <b>AppActivate method<\/b>. But you probably already knew that because it is the same as the way it works in VBScript. These two lines of code are seen&nbsp;here:<\/p>\n<pre class=\"codeSample\">[void]$wshShell.run(\"calc\")\n[void]$wshshell.AppActivate(\"calculator\")<\/pre>\n<p>Now we need to pause for a little bit to make sure the application is completely loaded and in the foreground prior to sending key strokes to it. So we use the <b>Start-Sleep<\/b> cmdlet to do this. In VBScript we would use <b>wscript.sleep<\/b>. It is essentially the same thing. Once we are certain the application is in the foreground, we use the <b>SendKeys<\/b> method to send key strokes to the application. In this example we add 1+2 and press <b>ENTER<\/b>. We wait a bit, and then send more key strokes to multiply the previous result by the number 5, and the we press <b>ENTER<\/b> again. This is seen&nbsp;here:<\/p>\n<pre class=\"codeSample\">Start-Sleep -milliseconds 100\n$wshShell.SendKeys(\"1{+}2~\")\nStart-Sleep -milliseconds 100\n$wshShell.SendKeys(\"*5~\")<\/pre>\n<p>What does all this have to do with your question, RS? It might be possible to use <b>SendKeys<\/b> to control your external application. It is just something to think about. However, I have a better idea in this particular case. How about if we write our own password generator? If you think this will be cool, read on. If not, you are free to take the <b>SendKeys<\/b> example and use that to try to automate your password generator program. It won\u2019t hurt my feelings. I had fun writing&nbsp;it.<\/p>\n<pre class=\"codeSample\">Param($pwdPass = 2)\nFunction CreatePassword()\n{\n $rnd = new-object system.random\n for($i = 1 ; $i -le $pwdPass ; $i++)\n {\n   LtrFmAscii($rnd.Next(33,47))\n   LtrFmAscii($rnd.Next(48,57))\n   LtrFmAscii($rnd.Next(65,90))\n   LtrFmAscii($rnd.Next(97,122))\n }\n} #end CreatePassword\nFunction LtrFmAscii($ascii)\n{\n  $script:password += [char]$ascii\n} #End LtrFmAscii\nFunction DisplayPassword()\n{\n  $script:password\n} #end DisplayPassword\n# *** ENTRY TO SCRIPT ***\n$script:password = $null\nCreatePassword\nDisplayPassword<\/pre>\n<p>The first thing we do in this script is define a command-line parameter named <b>pwdPass<\/b>. This parameter is used to control how many times we work through the <b>CreatePassword<\/b> function. Each pass through the <b>CreatePassword<\/b> function adds one special character, one number, one lowercase letter, and one uppercase letter. This line of code is seen here where by default we set the value of the <b>$pwdPass<\/b> variable equal to 2:<\/p>\n<pre class=\"codeSample\">Param($pwdPass = 2)<\/pre>\n<p>You may be thinking that we just said the command-line parameter is <b>pwdPass<\/b>, but we said the variable <b>$pwdPass<\/b> contains the value 2. How is this possible? Well, when the script is run from the command line, we use <b>-pwdPass<\/b> as seen here:<\/p>\n<p><img decoding=\"async\" height=\"333\" alt=\"-pwdPass used from the command line\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/hey1016\/hsg_rndpwd01.jpg\" width=\"450\" border=\"0\" \/> <\/p>\n<p>&nbsp;<\/p>\n<p>You can also see that the command line parameter is not case sensitive.<\/p>\n<p>Next, we create the <b>CreatePassword<\/b> function where we first create an instance of the <b>System.Random<\/b> .NET Framework class and store the object in the <b>$rnd<\/b> variable. Next, we use the <b>for<\/b> statement to create a loop that obtains random numbers from four different sections of the ASCII character table. Each random number from the specified numeric range is sent to the <b>LtrFmAscii<\/b> function where we will turn the integer into a character. The <b>CreatePassword<\/b> function is seen&nbsp;here:<\/p>\n<pre class=\"codeSample\">Function CreatePassword()\n{\n $rnd = new-object system.random\n for($i = 1 ; $i -le $pwdPass ; $i++)\n {\n   LtrFmAscii($rnd.Next(33,47))\n   LtrFmAscii($rnd.Next(48,57))\n   LtrFmAscii($rnd.Next(65,90))\n   LtrFmAscii($rnd.Next(97,122))\n }\n} #end CreatePassword<\/pre>\n<p>The next thing we need to do is create the helper function <b>LtrFmAscii<\/b>. This function is used to change the integer obtained from the <b>CreatePassword<\/b> function into a character (an instance of a <b>system.char<\/b><b>valuetype<\/b> class). We use the <b>+=<\/b> operator to concatenate the characters into a single string we can use for our password. We use the script-level variable <b>$password<\/b> to hold the string that is being built. This is seen&nbsp;here:<\/p>\n<pre class=\"codeSample\">Function LtrFmAscii($ascii)\n{\n  $script:password += [char]$ascii\n} #End LtrFmAscii<\/pre>\n<p>When we have the generated password, we go to the <b>DisplayPassword<\/b> function. The <b>DisplayPassword<\/b> function is perhaps not too sophisticated\u2014all it does is print the password to the screen. However, in future versions of this script, we may want to write the password to a text file, or send the password by e-mail to the newly created user&#8217;s manager. There is a lot of potential here so we decided to put the logic into a separate function that is seen&nbsp;here:<\/p>\n<pre class=\"codeSample\">Function DisplayPassword()\n{\n  $script:password\n} #end DisplayPassword<\/pre>\n<p>That&#8217;s it for the functions. The entry point to the script declares the <b>$password<\/b> variable as a script-level variable, which means it can be used anywhere within the script. To do this, we use the script modifier as seen here:<\/p>\n<pre class=\"codeSample\">$script:password<\/pre>\n<p>We go ahead and initialize the <b>$password<\/b> variable by setting it equal to <b>$null<\/b>. The next thing we do is call the <b>CreatePassword<\/b> function and the <b>DisplayPassword<\/b> function. The entry to the script is shown&nbsp;here:<\/p>\n<pre class=\"codeSample\"># *** ENTRY TO SCRIPT ***\n\n$script:password = $null\nCreatePassword\nDisplayPassword<\/pre>\n<p>So, RS, that is about all there is to generating random passwords. In our next article, we will show you how to incorporate it with creating users in Active Directory. As they say in Australia (deep-southern Australia), &#8220;Y&#8217;all come back now, ya hear?&#8221;<\/p>\n<p><font class=\"Apple-style-span\" face=\"Verdana\" size=\"3\"><span class=\"Apple-style-span\"><b><b>Ed Wilson and Craig Liebendorfer, Scripting Guys<\/b><\/b><\/span><\/font><\/p>\n<p><font class=\"Apple-style-span\" face=\"Verdana\" size=\"3\"><b><\/b><\/font><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! I am trying to create a bunch of users via script, but I am having problems dealing with their passwords. I do not want to give everyone the same password, and I do not want to have to manually create a hundred passwords and store them in a file, so I am [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[3,4,21,45],"class_list":["post-55003","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-scripting-guy","tag-scripting-techniques","tag-string-manipulation","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! I am trying to create a bunch of users via script, but I am having problems dealing with their passwords. I do not want to give everyone the same password, and I do not want to have to manually create a hundred passwords and store them in a file, so I am [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/55003","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\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=55003"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/55003\/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=55003"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=55003"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=55003"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}