Generate Random Passwords with Powershell

by alexpav 14. May 2009 10:31

Recently, I ran across the need to generate a random password, and decided to write a quick PowerShell script to accomplish this task. I wanted to make sure that I can supply the desired password length and that there are two different levels of complexity: letters (uppercase and lowercase) and numbers, and letters (uppercase and lowercase), numbers, and special characters.

Since I have Powershell v2 on my Windows Server 2008 R2 laptop, that’s what I will use. Powershell v2 contains a nifty random generator cmdlet (get-random), and it will be very useful. If you don’t yet have Powershell V2 installed, grab the latest version listed here: http://blogs.msdn.com/powershell/pages/download-windows-powershell.aspx . As of the time of the writing, CTP3 was the latest released version – download it from the Microsoft Download Center: http://go.microsoft.com/fwlink/?LinkID=131969 .

If you are impatient like me, just grab the script file here:  

pwgen.zip (1.47 kb)

But to truly understand how it works, read on... 

When I started thinking about the problem at hand, I already knew that there would be two different parameters that I need to pass to the script: password length, and password complexity. Getting these values into the script can be achieved with param statement in Powershell:

 param (

[string]$pwcomplexity = $(Read-Host "Please select password complexity. 1 for alphanumeric, or 2 for alphanumeric plus special characters"),

[string]$pwlength = $(Read-Host "Please enter the desired password length")

) 

 

The use of the param statement allows us to pass the values to the script using the –pwcomplexity and –pwlength arguments. The use of the Read-Host statement will allow us to simply run the script – we will be prompted to enter these values as the script executes. Additionally, note the use of the [string] cast. We want to make sure that the input values are strings, not integers, hence the cast .

Before we move on, let’s pre-define the character strings to be used in our passwords. I wanted to have a set with letters (uppercase and lowercase) and numbers, and another set with letters, numbers, and special characters. Note that this is two lines of code (broken up for ease of viewing).

 $strComplex =

"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T",

"U","V","W","X","Y","Z","1","2","3","4","5","6","7","8","9","0","a","b","c","d",

"e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z”,

"!","@","#","$","%","^","&","*","(",")","_","=","~","?","<",">"

$strSimple =

"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T",

"U","V","W","X","Y","Z","1","2","3","4","5","6","7","8","9","0","a","b","c","d","e","f",

"g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z”

 

 Because we assign values separated by commas, the $strComplex and $strSimple become character arrays. In an array, we can query array’s value by supplying its position within the array. For example, $strSimple[3] will return capital letter D, since the first character in the array has a position of zero. So $strSimple[0] is letter A. You get the idea – we will use a random number to peek inside the array and get characters for our password.

Now we need to process the arguments – make sure that they are valid, and configure options for password generation based on input.

  if ($pwcomplexity -eq "1")#simple password

{

    $strCharacters =  $strSimple

}

elseif ($pwcomplexity -eq "2")#complex password

{

   $strCharacters =  $strComplex

}else

#not sure what was entered, let's assume complex password

{

     write-warning "Invalid passwod complexity supplied, generating a complex password (equivalent to option 2)"

     $strCharacters =  $strComplex

}

if ($pwlength -notmatch "\d+")

#validate that what was entered is a digit using regular expressions.

{

   #not a digit, assume that desired length is 8 characters

   write-warning "Invalid password length supplied, generating an 8 character password instead"

$pwlength = 8

} 

 

Note the use of the regular expression matching with the –notmatch parameter. “\d+” means “any number of digits only”. So if someone types in a letter or any other non-digit during the password length input, the script will trigger the contents of the if block, write a warning to the screen, and assume the default length of 8 characters.

At this point in the script, we have our desired password generator options all taken care of. Let’s write a function to generate the random password. By making it a function, we have a better ability to call it multiple times. Hint: making this a function will come handy as we write the rest of our script.

function generate-password

{

   $pw = $null

   for ($i=0;$i -lt $pwlength; $i++)

   {

     $pw += get-random -InputObject $strCharacters

    }

    return $pw

} 

 

In the function, we will store our generated password in a $pw variable. It is a good idea to reset it so that any previous data that could possibly be stored in that variable is erased before we proceed. So we will set it to $null to begin with. Then, we run a FOR block, which will iterate while the $i variable is between 0 and one less than the desired password length, incrementing $i by one each time the block loops. For example, if our desired password length is 8 characters, we will run it 8 times, with $i being 0,1,2,3,4,5,6, and 7. Within the FOR block, we will use a PowerShell v2 function called get-random (you can find out about get-random in a very cool Microsoft TechNet article here: http://www.microsoft.com/technet/scriptcenter/topics/winpsh/getrandom.mspx)

In a nutshell, get-random will generate a random number or pick a random object from an array. Remember the arrays we setup in the beginning? Well, we will now feed one of the arrays (depending on password complexity requirements) into the get-random cmdlet using the –InputObject parameter. We will get back a random character from that array. Then, we will add this character to the $pw string by using the += operator, which means “take whatever $pw had before, and add the result of the get-random command to it”. Basically, we will continue to increment $pw with random characters. Pretty cool! At the end, we return the password when the function is done.

A function itself does not run as part of script processing. You have to explicitly call it. Let’s do that by assigning the return value of the function to the $genPassword variable:

 $genPassword = generate-password 

 

Great, now the $genPassword variable contains our password. But is it a good password? What if the random generator did not randomly pick any numbers? Or there are no lower case letters? Or no special characters? To make sure that the password meets our requirements, let’s check it.

First, let’s check that the password has the desired length:

if ($genPassword.length -ne $pwlength)

{

   write-warning "Failed to generate the password due to length mismatch"

   $genPassword = $null

   break

}

 

Ok, something went wrong if we ran the loop 8 times but did not get an 8 character password. Let’s exit the whole script with a break statement, and try again. We’ll inform the operator with the write-warning message. Assuming that this part works, let’s check the complexity. And if we don’t meet the complexity requirements, let’s try to re-generate our password by calling the function over and over again, until the complexity requirements are met. We will use a while block, which basically loops over and over again until a pre-defined condition is met. Let’s use the $checkpasswordcomplexity boolen variable (true or false) to control it.

 while ($checkcomplexity -eq $true)

{

   if (($pwcomplexity -eq "1") -and ($genPassword -match "^.*(?=.{$pwlength,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$"))

  {

     write-host "Complexity level 1 validated - at least one lower case, one upper case, and one digit"

     write-host "The password is: $genPassword"

     $checkcomplexity = $false

  }

  elseif (($pwcomplexity -eq "2") -and ($genPassword -match "^.*(?=.{$pwlength,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*()_=~?<>]).*$"))

  {

     write-host "Complexity level 2 validated - at least one lower case, one upper case, and one digit"

     write-host "The password is: $genPassword"

     $checkcomplexity = $false

  }

  else

  {

     write-warning "$genPassword : Complexity validation failed, regenerating..."

     $genpassword=$null$genPassword = generate-password

  }

}

 

So, if the desired complexity is “1” (simple password), and if we can match a regular expression that validates for lowercase, uppercase, and digits, we are good to go and can write the password to console. If the desired complexity is “2” (complex password), and if we can match a regular expression that validates lowercase, uppercase, numbers, and special characters, then we are also good to go and can write the password to console. Otherwise, something went wrong and we randomly picked a too simple of a password, so let’s re-run the generate-password function.

If you are confused or scared of regular expressions, don’t be. Just read this cool MSDN article on .Net regular expressions and you will feel better. Maybe. We will try to talk more about regular expressions in later articles.

As you can see, with the power of PowerShell v2, you can do really cool things, such as generate random passwords. Script on, infradevs!

-alexpav

Currently rated 5.0 by 3 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Powershell | Scripting | Security

Cross Browser Support in Microsoft Office SharePoint Server 2007

by sanpan 29. April 2009 10:00

I've been working with a customer that has a very mixed client environment, to help achieve a common user experience in MOSS across all the various browsers in their environment (mostly IE 5-8, FireFox and Safari).  One of the ways we can move towards accomplishing this is to disable client integration, but regretfully this disables many of the features that make MOSS a great collaboration platform.

The list below is a work in progress, I'm looking to identify fixes or addon offerings (such as Telerik's RadControls for MOSS http://www.telerik.com/products/aspnet-ajax/sharepoint.aspx) that can provide the desired functionality in a cross-browser environment.  There's also a codeplex project specifically for FireFox support at http://wssfirefox.codeplex.com/ but this won't meet my requirement for a common experience across ALL browsers. 

I'd appreciate any comments/feedback.

Feature Possible Solution
Date picker control telerik
Microsoft Office Visio 2007 diagram creation is this a desired feature
Microsoft Office InfoPath 2007 integration manually open/edit infopath forms
Single sign-on none identified
Presence information none identified
Microsoft Office PowerPoint 2007 integration none identified
Web discussions deprecated feature
Spreadsheet and Database integration none identified
Slide library and Office PowerPoint 2007 integration none identified
Rich Text Editor field telerik
Datasheet view telerik
File upload and copy telerik
Edit in Datasheet view telerik
Edit In (Microsoft Office application) none identified
Explorer view telerik
List attachments testing a possible solution
Multiple file upload telerik
New Document use upload instead
Part to Part Connections none identified
People Picker works but doesn't resolve domain\username
Rich text Toolbar telerik
Send To works within the farm
Date Picker Control telerik
Slide Library none identified
Excel Web Access not compatible with Safari, no identified fix
Open in Excel none identified
Open Snapshot none identified
Sorting and Filtering (Excel Services) telerik datagrid as an alternative
Signing forms (Forms Server) can view but cannot sign
Rich Text (InfoPath) none identified (explore if telerik control can be used)
Rich text editing in Forms Server forms none identified (explore if telerik control can be used)

 

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

SharePoint

Quick steps for rebranding an acquired company with your email domain for basic email integration

by sanpan 2. April 2009 09:35

With the current economic climate, we're seeing an uptake in merger and aquisition activity across our customers.  One of the first things organizations want to do in these scenarios is often to rebrand the new aquisition to their own name, including email.  Although its not trivial to accomplish a full email consolidation, there are steps we can take to rapidly update the external email addresses of an organization and provide basic interoperability.  In most cases this can be done even without WAN connectivity.  The example below discusses Exchange to Exchange, but this same concept will work with most email systems. 

 Here are the steps: 

1.       Identify and address any email address collisions

a.       Consideration: how the new-hire process can be modified at each location to ensure no future collisions are created

2.       Identify and address any email policy differences to ensure consistent user experience, including but not limited to:

a.       Message size limits

b.      Anti-spam/content filtering rules

c.       Virus filtering experience (quarantine policies, notification format)

3.       Establish SMTP connectors within each Exchange environment

4.       Import account information from child companies to parent and establish forwarders

a.       Consideration: how you will keep this in sync moving forward if account information changes

5.       Configure child companies as non-authoritative for @parent.com

a.       See http://support.microsoft.com/kb/823158 for details. 

6.       Update child companies to have primary SMTP addresses @parent.com via recipient policy or a script 

a.       Keep any existing SMTP addresses (at least for the short term) for work continuity and applications/subscriptions

7.       Import account information across the organization (as a contact) to each child company to ensure everyone has the full GAL 

This will give you email interoperability.  Once you have WAN connectivity between each site, you can take an additional step -

 

To enable Free/Busy synchronization – this would allow calendaring between Exchange organizations and show free/busy information.  Use the IORepl tool, available at:

http://microsoft.com/downloads/details.aspx?FamilyId=E7A951D7-1559-4F8F-B400-488B0C52430E

 

This tool would also be used to consolidate/replicate public folders from the child organizations to the parent environment prior to collapsing those Exchange organizations.

   Here’s a high-level diagram of various mailflow scenarios.

  

Let us know if you have any questions, we hope this information is useful to you.

Currently rated 5.0 by 2 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Exchange

Where are the Exchange 2007 Unified Messaging Voicemail Greetings???

by alexpav 17. March 2009 13:01
 

Have you ever wondered where the Exchange 2007 Unified Messaging greetings are stored? Recently, a fellow colleague had an interesting dilemma. His customer asked him if there was a way to upload WAV files as user’s personal greetings. Such functionality exists for Auto Attendant prompts, but not for individual user mailboxes. But before we dive in to uploading WAV files as personal greetings, we need to better understand how these greetings are stored in Exchange 2007 Unified Messaging.

First, let’s review the different greeting types which exist in Exchange 2007 Unified Messaging:

·         Recorded Name (stored in Active Directory)

·         Personal Greeting (stored in the mailbox)

·         Out of the Office Greeting (stored in the mailbox)

Recorded Name

The personal greeting is stored as a binary value in Active Directory, in an attribute called ms-Exch-UM-Spoken-Name.  In order for this attribute to be populated, several things have to take place. First, the user must have an enabled mailbox on an Exchange 2007 mailbox server. Second, the mailbox must be enabled for Exchange 2007 Unified Messaging. Finally, the user must dial the UM Outlook Voice Access number and use Personal Options to record the name. If the user does not perform the last step, Exchange 2007 Unified Messaging will auto-generate the recorded name based on the Display Name in Active Directory, however the auto-generated recorded name itself is not stored in AD. Instead, it is stored in memory of the Exchange 2007 Unified Messaging server.

Personal Greeting

Much like the custom recorded name, the personal greeting is a binary format value. However, instead of being stored in Active Directory, it is stored in the mailbox of the user. Similar three pre-requisites apply – Exchange 2007 mailbox, enabled for Unified Messaging, and user action to record the personal greeting via Outlook Voice Access.

So how does Exchange UM store the personal greeting? We already know that it is a binary value (in fact, it is a binary representation of a WAV file), and that it sits in the user mailbox. But where exactly is it?

Each user mailbox contains a hidden message area. This message area is not exposed in Outlook or Outlook Web Access, however it can be viewed using MAPI tools such as MFCMAPI, which is can be obtained from the Microsoft Download Center here. To use MFCMAPI, it is necessary to configure the Outlook profile in online mode (cached mode won’t work correctly), and also add the following registry key to view large binary values (HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Messaging Subsystem\MSMapiApps\SharedMemMaxSize= 0x00800000 (DWORD).

Let’s use MFCMAPI to explore the hidden message area of a mailbox. First, launch MFCMAPI, select the Session menu item, and click on Log On and Display Store Table. Then, select the online mode Outlook profile if prompted. You will see the configured MAPI instances in the top pane of the MFCMAPI window.

 

Figure 1 – Outlook Profile, Unrated Version

Right-click the actual Exchange mailbox, and click Open Store. A new window will open, displaying the Root Container on the left side. As you can see, this is the raw view of the mailbox as you can navigate familiar folders and see raw contents of messages.

Figure 2 – Raw Mailbox View, a.k.a. Too Much Info

Right-click the Root Container in the left pane, then click on Open Associated Contents Table. You will see one more window pop-up, displaying hidden messages which are contained in the mailbox. Scroll the top pane to the right and expand the Message Class column. You will see different message classes that exist. Of interest to us is the IPM.Configuration.Um.CustomGreetings.External message. If it is not visible, you may have to record the greeting by calling in to Outlook Voice Access. If no items are visible, it is likely that the Outlook profile is configured in Cached Mode. Click on the message with the IPM.Configuration.Um.CustomGreetings.External type. You will see the list of properties in the bottom pane. We are looking for the 0x7C09000A property (see Figure 3). Note that MFCMAPI cannot fully load it because it is quite large, but no worries, with our registry modification from earlier we will be just fine!

Figure 3 – Hidden Messages

Right-click it and select Edit Property as Binary Stream. As you will see, the Stream text (top window) displays the WAVEfmt in the top row – that’s the binary file format. The bottom window displays the actual hex string of the wav file (Figure 4)

 

Figure 4 – Binary Stream View

Out of the Office Greeting

The OOF greeting is very similar to personal greeting. It is also stored in the mailbox and can be accessed and dare I say it – modified - by mortals (non-Exchange UM server types) by using MAPI tools.

Conclusion

Now that you know where the Exchange 2007 Unified Messaging greetings are stored, you can better troubleshoot issues with greetings, and also do cool things such as write applications which allow users to upload a wav file as their greeting, enabling them to easily switch between multiple greetings without having to re-record them. We’ll plan to cover this for you in our future blog posts.

Currently rated 3.7 by 3 people

  • Currently 3.666667/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Exchange | MAPI | Unified Messaging

Security Considerations in High Performance Computing

by sanpan 20. December 2008 10:50

Another Security Tip of the Month article was just published.  I worked on this one with our resident HPC and Management expert.  Richard gets credit for the HPC knowledge, and I put pen to paper.  (fingers to keyboard?).  You can find "Security Considerations in High Performance Computing" at http://technet.microsoft.com/en-us/library/dd339638.aspx.

 

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Security

Who, Where, When? Simple Tools for Auditing in the Enterprise

by sanpan 16. October 2008 10:57
Our article, "Who, Where, When? Simple Tools for Auditing in the Enterprise" was just published as the Technet Security Tip of the Month for October 2008 at http://technet.microsoft.com/en-us/library/dd164376.aspx.  We do have more complex examples of using scripting for reporting and data analysis of Windows Security logs, but haven't written up a post yet.  Let us know if you're interested.

You can also take a look at http://technet.microsoft.com/en-us/library/cc716276.aspx for the past Technet Security Tip of the Month articles.

Currently rated 4.7 by 3 people

  • Currently 4.666667/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Infradevs | Security

What is an Infradev?

by sanpan 15. October 2008 22:26

We've noticed that most technical people in the technology industry are classified as either infrastructure specialists or developers.  The challenge with this thinking is the fact that most infrastructure projects require customization through extensibility, and most development projects require understanding of the underlying infrastructure. The blending of the two traditionally separate worlds has been accelerating. For example, to deliver a Microsoft Exchange Server 2007 implementation (traditionally considered an infrastructure solution), one needs to be closely familiar with Windows Powershell, which is the management platform for Exchange. After a day with Powershell, it is trivial to recognize that general programming concepts, object oriented programming, and even .NET framework are necessary even when putting together system administration scripts for Exchange Server 2007. 

Similarly, delivering a pure development project is no longer simply development. Consider Microsoft Office SharePoint Server 2007 - in an enterprise deployment, the one will likely need to understand infrastructure components such as Active Directory, Network Load Balancing, Server Clustering, firewall ports, Kerberos, permissions, reverse proxies... The list goes on. 

Infradevs are a third group that blend the best of these two worlds, leveraging the power of best tool for the job, whether it is custom scripting with Windows Script and Powershell, or Visual Studio development of custom applications with the goal to increase efficiency of infrastructure deployment and reliability of infrastructure processes and operations.

A great example was a recent experience where our client was looking to accomplish a complex domain consolidation effort.  All conventional paths led them to a method using a large team of support engineers and a significant investment in third party tools.  Our Infradev solution for the client leveraged custom scripting and a revised process for the migration that decoupled unnecessary dependencies and yielded exceptional results.

We believe that the value in being an Infradev is removing some of the constraints that are found in out of the box solutions.  Any packaged product is developed with its largest constituents in mind, however those solutions can never account for the uniqueness found in every environment.  Thus, the skill set of an Infradev is the secret sauce that enables organizations to fully realize the value of their technology investments. 

Are you an Infradev?

Currently rated 5.0 by 2 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

General | Infradevs | Value

Welcome to the Infrastructure Development Blog

by alexpav 6. October 2008 14:32

Hello and welcome to the Infrastructure Development blog. Stay tuned in the next few days for great content about architecting, customizing, and deploying various complex infrastructure solutions in enterprise environments.

Currently rated 5.0 by 3 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Powered by BlogEngine.NET 1.4.5.0
Theme by Mads Kristensen