{"id":54113,"date":"2009-03-25T21:27:00","date_gmt":"2009-03-25T21:27:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2009\/03\/25\/hey-scripting-guy-how-can-i-change-the-passwords-of-multiple-local-computer-accounts\/"},"modified":"2009-03-25T21:27:00","modified_gmt":"2009-03-25T21:27:00","slug":"hey-scripting-guy-how-can-i-change-the-passwords-of-multiple-local-computer-accounts","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-change-the-passwords-of-multiple-local-computer-accounts\/","title":{"rendered":"Hey, Scripting Guy! How Can I Change the Passwords of Multiple Local Computer Accounts?"},"content":{"rendered":"<h2><img decoding=\"async\" class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\" \/> <\/h2>\n<p>Hey, Scripting Guy! We have certain accounts that are local accounts. These accounts are created when the computer is built, and the passwords are set and that is it. For as long as the computer exists, these accounts are never touched, and the passwords are never changed. To make matters worse, if indeed it can be worse, these account passwords are not really known. It seems that whoever built the PC made up a password for that account, and in order to actually log on to the account externally, we need to first go find the person who loaded the operating system onto the computer. Then he has to remember when the computer was built, and next he has to remember what password he was using during the time when the computer was built. <\/p>\n<p>If he gets stuck on remembering when the computer was built, we can use WMI to gather that information, but if he cannot remember what password he was using in that time frame, we are stuck. Most of the computers are special-purpose machines that are in remote locations. I am, to be frank, quite concerned about the password situation on these machines. In some cases, the computers have been operating for five years, and the password has never been changed. It will take a horribly long time if I have to do this all by hand. I would like to implement change control for these computers, and write a script that I can use to change the passwords for these local accounts. Of course, when I say I would like to write a script, I really mean I would like for you to write such a script so I can copy it. <\/p>\n<p>&#8211; TK<\/p>\n<p><img decoding=\"async\" border=\"0\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" height=\"5\" \/><img decoding=\"async\" class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\" \/> <\/p>\n<p>Hi TK,<\/p>\n<p>I was recently at the Microsoft office in Charlotte, North Carolina, in the United States. A friend who knows I like tea offered me a can and said, &#8220;Drink this, it&#8217;s great.&#8221; So I pulled the pop top on the can, took less than a single sip, and decided it really was not great. For me, there is no such thing as instant tea. Luckily, I happened to carrying my tea kit with me in my computer bag. So I got out my little tea pot the Scripting Wife gave me for Christmas, my little tin of Earl Grey tea, and my tea strainer that my friend Jit and Mrs. Jit gave me when I was in Canberra, Australia. <\/p>\n<p>I proceeded to brew myself a proper cup of tea. Tea should not be rushed. It should be savored and appreciated. User account management should not be rushed either, but one need not linger over a mouse for the next three weeks either. The graphical user interface is not something that needs to be savored. And while I do appreciate it from time to time, when I have a simple one-off task to perform, I do believe I could rapidly grow weary of seeing repeated warning boxes being displayed for each of several thousand changes that may need to be made. Clearly, this is a task that calls for a script.<\/p>\n<table id=\"EZC\" class=\"dataTable\" cellSpacing=\"0\" cellPadding=\"0\">\n<thead><\/thead>\n<tbody>\n<tr class=\"record\" vAlign=\"top\">\n<td>\n<p class=\"lastInCell\">This week we will be looking at scripting Windows PowerShell as it applies to local account management. This is an area that comes up from time to time and for which there are not an awful lot of resources from which to choose. We have these tasks in the Script Center Script Repository pretty well hidden away in the <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/scripts\/ds\/local\/default.mspx\" target=\"_blank\">Other Directory Services<\/a> category. There are some great scripts in the <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/csc\/scripts\/local\/default.mspx\" target=\"_blank\">Community-Submitted Scripts Center<\/a>. Local account management has been a favorite topic of the \u201cHey, Scripting Guy!\u201d articles over the years, and as a result we have a good selection of articles grouped together in the <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/local.mspx\" target=\"_blank\">\u201cHey, Scripting Guy!\u201d archive<\/a>. The most extensive reference you will find is the MSDN coverage of the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa772237(VS.85).aspx\" target=\"_blank\">WinNT ADSI provider<\/a>.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<div class=\"dataTableBottomMargin\"><\/div>\n<p>Well, TK, I wrote a script called <b>ChangeUserPassword.ps1<\/b>. It reads the contents of a text file with all the computer names that house the account whose password you need to change. A VBScript version of this script can be found in the <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/csc\/scripts\/local\/users\/cscla011.mspx\" target=\"_blank\">Community-Submitted Scripts Center<\/a>.<\/p>\n<pre class=\"codeSample\"><pre class=\"codeSample\">$computers = Get-Content -path C:\\fso\\computers.txt\n$user = \"aUser\"\n$password = \"MyNewPassword!\"\nForeach($computer in $computers)\n{\n $user = [adsi]\"WinNT:\/\/$computer\/$user,user\"\n $user.SetPassword($Password)\n $user.SetInfo()\n}\n<\/pre>\n<p>To change the user account password remotely using the graphical user interface, you open up the Computer Management utility. Then you right-click the little computer at the top of the screen and choose <b>Connect to another computer<\/b> from the <b>Action<\/b> menu. Depending on the speed of the network or the speed of the computer, you may see a spinning disk or you may see an hour glass or you may see a message that says, \u201cConnecting to remote computer. Please wait.\u201d After you find the <b>Local Users and Groups<\/b> section under <b>System Tools<\/b>, right-click the user account. When you select <b>Set Password<\/b> and click past the long warning message, you are presented with the nice dialog box seen here:<\/p>\n<p><img decoding=\"async\" border=\"0\" alt=\"Image of the Computer Management tool\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2009\/march\/hey0325\/hsg-3-25-9-1.jpg\" width=\"384\" height=\"243\" \/> <\/p>\n<p>&nbsp;<\/p>\n<p>Even if the process were as fast as it is on the local computer, it still takes time. If you have to change the password for a particular account on a thousand computers, the graphical utility simply is not a scalable solution.<\/p>\n<p>That\u2019s where the script comes in. The first thing we do is use the <b>Get-Content<\/b> cmdlet to read a text file that contains the names of all the computers that have accounts whose password we wish to change. The <b>Get-Content<\/b> will return an array with each element of the array holding the name of one of the computers. There is nothing special about the <b>computers.txt<\/b> file. It is a simple text file with the names of computers on individual lines. This is seen here:<\/p>\n<p><img decoding=\"async\" border=\"0\" alt=\"Image of the New User dialog box\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2009\/march\/hey0325\/hsg-3-25-9-2.jpg\" width=\"500\" height=\"199\" \/> <\/p>\n<p>&nbsp;<\/p>\n<p>We use the <b>Get-Content<\/b> cmdlet, and each line from the <b>computers.txt<\/b> file is printed on its own individual line:<\/p>\n<pre class=\"codeSample\">PS C:\\&gt; Get-Content -Path C:\\fso\\Computers.txt\nVista\nBerlin\nLima\nSydney\n<\/pre>\n<p>In this example, we use the <b>Get-Content<\/b> cmdlet to read the text file. We store the returned data in a variable named <b>$computers<\/b>. On the next line of the example, we use the <b>[0]<\/b> to refer to the first item in the array. When it is printed out, we see that it holds the name <b>Vista<\/b>, which incidentally was the first name displayed in the previous example:<\/p>\n<pre class=\"codeSample\">PS C:\\&gt; $computers = Get-Content -Path C:\\fso\\Computers.txt\nPS C:\\&gt; $computers[0]\nVista\nPS C:\\&gt;\n<\/pre>\n<p>We&nbsp;read the contents of the <b>computers.txt<\/b> file by using the <b>Get-Content<\/b> cmdlet, and we store the returned array of text in the <b>$computers<\/b> variable:<\/p>\n<pre class=\"codeSample\">$computers = Get-Content -path C:\\fso\\computers.txt<\/pre>\n<p>Now we specify the name of the user whose password we are going to change. We assign the username to the <b>$user<\/b> variable:<\/p>\n<pre class=\"codeSample\">$user = \"aUser\"<\/pre>\n<p>Then we specify the new password for the user. It is also a straightforward value assignment to a variable as seen here:<\/p>\n<pre class=\"codeSample\">$password = \"MyNewPassword!\"<\/pre>\n<p>If you are uncomfortable with including the user password in the text of the script, you can easily use the <b>Read-Host<\/b> cmdlet to prompt you to type the password when you run the script. This is shown here:<\/p>\n<pre class=\"codeSample\">PS C:\\&gt; $password = Read-Host -Prompt \"Enter new password for the user\"\nEnter new password for the user: NewPassword1\nPS C:\\&gt; $password\nNewPassword1\nPS C:\\&gt;\n<\/pre>\n<p>You will perhaps notice that when using the <b>Read-Host<\/b> cmdlet to solicit the password, the password is displayed as plain text. If this is uncomfortable to you, it is possible to mask the password by specifying the <b>\u2013asSecureString<\/b> parameter. Notice that when the password is typed, it is masked with a series of asterisks. When we try to retrieve the password from the <b>$password<\/b> variable, we are told that the <b>$password<\/b> variable contains an instance of a <b>System.Security.SecureString<\/b> object:<\/p>\n<pre class=\"codeSample\">PS C:\\&gt; $password = Read-Host -prompt \"Enter new password for user\" -asSecureString\nEnter new password for user: ***********\nPS C:\\&gt; $password\nSystem.Security.SecureString\n<\/pre>\n<p>Next we need to work our way through the array of computer names stored in the <b>$computers<\/b> variable. When we hear the word array, we can immediately think <b>ForEach<\/b>, just like in VBScript. We use the <b>ForEach<\/b> statement to walk through the array of computers. The <b>$computer<\/b> variable is used as our placeholder to keep track of where we are in the array:<\/p>\n<pre class=\"codeSample\">ForEach($computer in $computers)\n{\n<\/pre>\n<p>It is time to connect to the user object. To do this, we use the <b>[adsi]<\/b> type accelerator and give it the <b>WinNT ADS<\/b><b>I<\/b> provider. We talked about the technique of connecting to local objects on <a href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/qanda\/mar09\/hey0323.mspx\" target=\"_blank\">Monday<\/a>. Refer to that article for a more complete discussion of the <b>WinNT ADSI<\/b> provider.<\/p>\n<p>We give the <b>WinNT ADSI<\/b> provider the name of the computer contained in the <b>$computer<\/b> variable, and the name of the user that is specified in the <b>$user<\/b> variable. The second user listed is a hint to ADSI to tell it what kind of object we are working with. We store the returned user object in the <b>$user<\/b> variable as seen here:<\/p>\n<pre class=\"codeSample\">$user = [adsi]\"WinNT:\/\/$computer\/$user,user\"<\/pre>\n<p>Now we call the <b>SetPassword<\/b> method and give it the password we stored in the <b>$Password<\/b> variable:<\/p>\n<pre class=\"codeSample\">$user.SetPassword($Password)<\/pre>\n<p>When we are finished changing the password, we call the SetInfo method to write the updates back to the account database:<\/p>\n<pre class=\"codeSample\">$user.SetInfo()\n}\n<\/pre>\n<p>TK, thanks for asking this question. We hope you will join us tomorrow as we present the final installment of our Local Account Management Week. Until tomorrow, take care.<\/p>\n<p>&nbsp;<\/p>\n<p><b>Ed Wilson and Craig Liebendorfer, Scripting Guys<\/b><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! We have certain accounts that are local accounts. These accounts are created when the computer is built, and the passwords are set and that is it. For as long as the computer exists, these accounts are never touched, and the passwords are never changed. To make matters worse, if indeed it can [&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":[46,197,23,24,3,45],"class_list":["post-54113","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-computer-accounts","tag-local-account-management","tag-local-accounts-and-windows-nt-4-0-accounts","tag-other-directory-services","tag-scripting-guy","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! We have certain accounts that are local accounts. These accounts are created when the computer is built, and the passwords are set and that is it. For as long as the computer exists, these accounts are never touched, and the passwords are never changed. To make matters worse, if indeed it can [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/54113","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=54113"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/54113\/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=54113"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=54113"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=54113"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}