Tuesday, May 19, 2015

Office 365 - Licensing Users in Bulk

If you've signed your business up for Office 365, you are probably well aware of their license offerings and that you must assign them to users as you go.  You may be using a variety of licenses such as the Exchange Standard license or the Office Subscription license.  If you automate user creation, you can add a license at creation time or after they are already created.  In this example, I'll show how to license user's who are already created.

If you are unsure on how to connect to your instance of Office 365, please see my other blog post on connecting: Connect to Office365

First, you need to find your AccountSKUID

 Get-MsolAccountSku  

This will return a column called AccountSkuID.  You will insert this into the script below where you see the term AccountSkuID.

This example shows how you can feed a list of existing users via a txt or csv file.  The file I use only has one column with no header.  This list contains the user ID portion of the user's email address only.  For example if the user's email address is 12345@mydomain.com, the user ID is 12345.

 import-module msonline  
 $Username = "admin@yourdomain.com"  
 $Password = ConvertTo-SecureString 'P@$$w0rd' -AsPlainText -Force  
 $cred = New-Object System.Management.Automation.PSCredential $Username, $Password  
 connect-msolservice -credential $cred  
 $users = Get-Content c:\scripts\msolusers.csv  
 foreach($user in $users){  
 set-msoluserlicense -userprincipalname $user@yourdomain.com -addlicenses AccountSkuID:OFFICESUBSCRIPTION  
 }  

Alternatively, if you'd like to license all user's who are currently in your Office 365 system, use the following script:


 import-module msonline  
 $Username = "admin@yourdomain.com"  
 $Password = ConvertTo-SecureString 'P@$$w0rd' -AsPlainText -Force  
 $cred = New-Object System.Management.Automation.PSCredential $Username, $Password  
 connect-msolservice -credential $cred  
 $users = Get-MsolUser -all | select userprincipalname  
 foreach($user in $users){  
 set-msoluserlicense -userprincipalname $user -addlicenses AccountSkuID:OFFICESUBSCRIPTION  
 }  

Disclaimer: All scripts and other powershell references on this blog are offered "as is" with no warranty.  While these scripts are tested and working in my environment, it is recommended that you test these scripts in a test environment before using in your production environment.

Wednesday, August 27, 2014

How to Connect to Office 365


In this post, I am going to simply discuss how to connect to Office 365 using Powershell.  With Powershell, you can manage and automate several tasks in Office 365, which will make your life much easier.  Some of the tasks I have automated are user account creation, distribution group memberships, and licensing.  I will outline connecting to Microsoft Online, where you can manage items such as accounts and licensing.  I will also cover how to connect to Exchange Online, which is more directed at mailbox related tasks.

Required Components

Before connecting, you'll need to install 2 components on your PC: the Microsoft Online (MSOL) Sign in Assistant, and the Azure Active Directory Module.  Keep in mind, the MSOL Sign in Assistant must be installed before you can install the Azure AD Module.  Here is where these can be obtained:


MSOL Sign in Assistant
Azure AD Module



Making the Connection

After you have finished installing the required components, open a new Powershell session.  The first thing we are going to do is import the MSOL module.


 import-module msonline  

Next, we need to initiate the connection.


 connect-msolservice  

You will be prompted for your Office 365 administrator login credentials.



Connecting to Exchange Online

Again, Exchange Online is useful for more mailbox related functions.  If you need to add a user to a distribution group, this is where you'll turn.  First, we need to capture the administrator credentials for your Exchange Online domain.  You will be prompted for your username and password.


 $credential = get-credential  


Next, lets store the session cmdlet in a variable called $Session.


 $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $credential -Authentication Basic -AllowRedirection  

Now, we initiate the session.


 Import-PSSession $Session  

When you're finished with your session, it's a good idea to disconnect gracefully.  I'm not sure what the default connection time-window is for Exchange Online, but I do know there is a small limit to the number of simultaneous connections you can have open for your domain.  If you have to many sessions open that you didn't disconnect, you won't be able to reconnect for a duration of time.  Here's how to disconnect:


 remove-pssession $Session  


That's all there is to connecting to Office 365.  I hope to add more posts centered around Office 365 in the near future that will show you how perform everyday tasks and setup some automation.

Friday, August 1, 2014

Creating a Menu with Powershell

So today we are going to talk about how you can create a menu in Powershell.  Menus can be useful for creating simple interfaces to perform everyday tasks.  You might create a menu for a user who has no knowledge of scripting whatsoever so that they can easily perform a task they otherwise couldn't.  This article is intended for those with little scripting experience and the topics I will cover include:

1. Creating a function
2. If/Then logic
3. Using Read-Host to accept user input
4. Using Write-Host to display output
5. Putting your script to sleep for an interval of time

Creating a Function

A function can be just about anything you want it to be.  I am going to be using a function to group several lines of my script into one command called "MainMenu".  I can call this group of lines in my script by simply typing the name of the function.  So let's create our menu:


 function mainmenu{  
 cls  
 echo "---------------------------------------------------------"  
 echo ""  
 echo ""  
 echo "    1. Open Notepad"  
 echo "    2. Open Calculator"  
 echo "    3. Exit"  
 echo ""  
 echo ""  
 echo "---------------------------------------------------------"  
 $answer = read-host "Please Make a Selection"  
                 }  

In the code block above, I've created a simple menu.  I am storing the read-host command in a variable called "$answer".  For now, everything else is just for looks, so lets add some if statements to handle the user input requested by read-host.


If Statements

We can use If statements to filter user input in our menu.  If a user presses 1, we want notepad to open.  If you user presses 2, we want them to see a calculator show up on their screen.  Here how it works:


 if ($answer -eq 1){notepad}  
 if ($answer -eq 2){calc}  

This syntax is fairly simple.  We start our statement with the word "if".  Next we take our user input which is now stored in the variable "$answer" and test it against something.  In this case, we are explicitly saying if $answer is equal to 1, open notepad.  If answer is equal to 2, open calculator.  In this example, we are only using the -eq (equals) comparison operator.  Other comparison operators you can use are:

-ne (not equal to)
-gt (greater than)
-lt (less than)
-ge (greater than or equal to)
-le (less than or equal to)

I'm going to do something a little different for option 3, exit.  I'm going to create another function with if statements that will ask the user if they are sure they want to exit and allows them to answer yes or no.  I will call this function "areyousure".  Also, I will want to place this function ahead of where I will be using it in my script.  Can't call the function if it doesn't know about it right?  For convenience, I will just go ahead and place it at the top of my script (see full script code at end of page for example).


 function areyousure {$areyousure = read-host "Are you sure you want to exit? (y/n)"  
           if ($areyousure -eq "y"){exit}  
           if ($areyousure -eq "n"){mainmenu}  
                     }  
            


So now if a user presses 3 in our menu to exit, they'll be prompted with the question (using read-host again) "Are you sure you want to exit? (y/n).  As you can see in my if statements, if they press "y", powershell will exit.  If they press "n", it calls my "mainmenu" function and returns them to the main menu to start all over.  But what if they type something else?  Any other input will break the script.  Lets add something else to handle that.


 function areyousure {$areyousure = read-host "Are you sure you want to exit? (y/n)"  
           if ($areyousure -eq "y"){exit}  
           if ($areyousure -eq "n"){mainmenu}  
           else {write-host -foregroundcolor red "Invalid Selection"   
                 areyousure  
                }  
                     }  

Notice the line starting with the word "else".  Else says we are going to take any user input besides what was used in our if statements and do something with it.

My else statement has 2 lines.  The first line will do a write-host and display the text on screen saying "Invalid Selection".  It will also color that text red so the user knows something isn't right.  The second line will re-run the "areyousure" function, giving the user the opportunity to decide once again whether or not they wish to exit.


Sleep Command

I'm going to add one more thing to our "mainmenu" function.  I want to create an else statement to handle other input besides the options offered.  This time, I will use "sleep" to display a message for 5 seconds, then return to requesting input.


 else {write-host -ForegroundColor red "Invalid Selection"  
       sleep 5  
       mainmenu  
      }  

So basically, just the word "sleep", and the time interval in seconds.  The menu will not accept input until this timer expires.

Finishing Up

So now our script is done!  I'm going to add one last line to the end of it that calls our "mainmenu" function so that the menu launches as soon as you open the script.



 #source ps1scripting.blogspot.com  

 #Areyousure function. Alows user to select y or n when asked to exit. Y exits and N returns to main menu.  
 function areyousure {$areyousure = read-host "Are you sure you want to exit? (y/n)"  
           if ($areyousure -eq "y"){exit}  
           if ($areyousure -eq "n"){mainmenu}  
           else {write-host -foregroundcolor red "Invalid Selection"   
                 areyousure  
                }  
                     }  
 #Mainmenu function. Contains the screen output for the menu and waits for and handles user input.  
 function mainmenu{  
 cls  
 echo "---------------------------------------------------------"  
 echo ""  
 echo ""  
 echo "    1. Open Notepad"  
 echo "    2. Open Calculator"  
 echo "    3. Exit"  
 echo ""  
 echo ""  
 echo "---------------------------------------------------------"  
 $answer = read-host "Please Make a Selection"  
 if ($answer -eq 1){notepad}  
 if ($answer -eq 2){calc}  
 if ($answer -eq 3){areyousure}  
 else {write-host -ForegroundColor red "Invalid Selection"  
       sleep 5  
       mainmenu  
      }  
                }  
 mainmenu  

The full script is above if you'd like to test it out, or modify it for your own purpose.  I've used menus like these for things like automating active directory account creation and deletion.  I also have Active directory queries setup to pull account specific info such as is the account locked, is the user's password expired, etc.

I have also created on for managing Office 365 accounts in the cloud using the MSOL powershell extensions.  With a little imagination, you can make everyday tasks much simpler to perform.

Also, for those just starting out... Try to adopt a formatting technique for you code early on that is easy to read.  Sure your script will still function with sloppy formatting, but it make troubleshooting issues so much easier.  It also makes it easier for others who may be working on a version of your script to tell what you are trying to do!

Thanks for stopping by!

Disclaimer: All scripts and other powershell references on this blog are offered "as is" with no warranty.  While these scripts are tested and working in my environment, it is recommended that you test these scripts in a test environment before using in your production environment.

Thursday, July 19, 2012

Powershell: Working with CSV Files

Today I'm going to talk about interacting with CSV files using powershell.  You may use CSV files to store values temporarily for a script, or you may be creating user accounts in Active Directory.  I'll be going over the process of how to read the file and declare variables for the headers.

The root of the whole process is importing a CSV file you've created.  The command to do this is:

Import-Csv pathtocsvfile

So that reads the file but how do we interact with the data?  The following example shows how you can process a csv file one row at a time.  This script simply echoes the data stored in the 2 columns in the csv file.



 $testcsv = import-csv c:\scripts\test.csv
  
 
  
 foreach($test in $testcsv)
  
   {
  
   $field1 = $test.field1
  
   $field2 = $test.field2
  
   
  
   Echo "$field1, $field2"
  
   }
  
     


So to break this out piece by piece:

1. This imports the csv file and stores it in the variable $testcsv

$testcsv = import-csv c:\scripts\test.csv

2.  This starts a "foreach loop" to process the csv file row by row.  The first variable, $test, can be named anything you want it to be.  I find it good practice to name it something relevent to the import-csv variable.  The second variable is the one we defined earlier for importing the csv file.

foreach($test in $testcsv)

3. Start the loop with a {

{

4.  This part is how we tie variables to the column headers in the csv file.  Again, name these what you want.  I like to name them after the column headers.  Set them equal to the $test variable dot (.) the column header they are tied to.

$field1 = $test.field1
$field2 = $test.field2


5.  This is the command we are going to run each row through.  Use the variables from the last step in the command.  Here we are telling powershell to echo field1 and field2.  Again, each row in the csv will run through this command.

Echo "$field1, $field2"

6.  Close the foreach loop with one of these }

}


My csv called test.csv looks like this:

Field1,Field2
data1,data2
data3,data3

When I run this script in powershell, I see the output of rows 1 and 2:



Create Active Directory Accounts from a CSV file with Powershell


Here's another example of how you can create Active Directory accounts using this method.





 ##########################################################################
  
 #     Create Active Directory Users from CSV
  
 #
  
 # This script will allow you to import users from a csv file
  
 # and create an active directory account for each of them. This requires
  
 # your domain and forest functional level to be 2008 R2.
  
 #
  
 # Source: ps1scripting.blogspot.com
  
 #
  
 ##########################################################################
  
 
  
 
  
 #Imports active directory module for running AD cmdlets
  
 Import-Module active directory
  
 
  
 #variable to store the data in adusers.csv
  
 $adusers = Import-csv c:\scripts\adusers.csv
  
 
  
 #This will process the CSV row by row. Each row contains information to create an active directory account for a user.
  
 foreach ($user in $adusers)
  
   {
  
   
  
   $username = $user.username
  
   $password = $user.password
  
   $firstname = $user.firstname
  
   $lastname = $user.lastname
  
   
  
   #create AD Acct #sets for username  #sets account name      #sets first name   #sets lastname  #enables account #sets display name        #sets login script path
  
   new-aduser -samaccountname $username -name "$lastname, $firstname" -givenname $firstname -surname $lastname -enabled $true -displayname "$lastname, $firstname" -scriptpath "\\server\loginscript.bat" -accountpassword (convertto-securestring $password -asplaintext -force)
  
   
  
   }  


I like to automate the Active Directory account creation process by using SQLCMD to select users from a SQL database and output them to a csv file.  Set these scripts up as scheduled tasks and let powershell do the rest!


Disclaimer: All scripts and other powershell references on this blog are offered "as is" with no warranty.  While these scripts are tested and working in my environment, it is recommended that you test these scripts in a test environment before using in your production environment.

Tuesday, July 17, 2012

Active Directory: Restore User from AD Recycle Bin

Ever deleted accidently deleted a user from active directory only to find that they need their account restored?  You can recreate the account manually but the SID (security identifier) will be different the second time around causing you to have to reestablish group membership, folder permissions, remount Exchange mailbox, etc. 

If you are running a Windows 2008 R2 domain environment with your domain and forest functional level at 2008 R2, there's a handy new feature call the Active Directory recycly bin.  This is only accessible through powershell which is kind of a bite, but in the script below, I've integrated a simple .net form with the cmdlet required to perform the object restore.  You will have to enable this feature first to use it and there's no going back if you do (why would you want to?).

To enable this feature, run powershell as administrator and run the following cmdlet and replace all instances of "yourdomain.com" with your AD domain info.

 Enable-ADOptionalFeature –Identity ‘CN=Recycle Bin Feature,CN=Optional Features,CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,DC=yourdomain,DC=com’ –Scope ForestOrConfigurationSet –Target ‘yourdomain.com’
  

As I mentioned above, I am using a simple .net form to create somewhat of a nice GUI for running this cmdlet.  I got the form from here:  http://technet.microsoft.com/en-us/library/ff730941 .  Check out this page if you'd like to learn more about it.

When you run the script below, you will see the following window pop up:

Simply type in the account name of the user that was deleted and click ok.  Like magic, the user with their SID is restored.  Their exchange mailbox is automatically reconnected (if it still exists and isn't connected to another account), and they should have access to any folder they did before.  It's like they were never deleted.  Here's the script, save it as Restore_AD_Account.ps1


 ######################################################################################  
#           Restore Active Directory Account  
# This script utilizes the Windows 2008 R2 AD ability to undelete an account  
# Your forest and domain functional level must be 2008 R2  
#  
# Source: ps1scripting.blogspot.com  
#  
#
#####################################################################################
  
  
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")   
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") 
  
   
#The objform.txt names the form window  
$objForm = New-Object System.Windows.Forms.Form   
$objForm.Text = "Restore Active Directory User"  
$objForm.Size = New-Object System.Drawing.Size(300,200)   
$objForm.StartPosition = "CenterScreen"
  
 
  
$objForm.KeyPreview = $True  
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Enter") 
  {$x=$objTextBox.Text;$objForm.Close()}})
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Escape") 
     {$objForm.Close()}})
  
 
  
#This labels the OK button
$OKButton = New-Object System.Windows.Forms.Button  
$OKButton.Location = New-Object System.Drawing.Size(75,120)  
$OKButton.Size = New-Object System.Drawing.Size(75,23)  
$OKButton.Text = "OK"  
$OKButton.Add_Click({$x=$objTextBox.Text;$objForm.Close()}) 
$objForm.Controls.Add($OKButton)
  
   
#This labels the cancel button
$CancelButton = New-Object System.Windows.Forms.Button 
$CancelButton.Location = New-Object System.Drawing.Size(150,120)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)  
$CancelButton.Text = "Cancel" 
$CancelButton.Add_Click({$objForm.Close()})  
$objForm.Controls.Add($CancelButton) 
  
#This gives a description in the window  
$objLabel = New-Object System.Windows.Forms.Label  
$objLabel.Location = New-Object System.Drawing.Size(10,20)   
$objLabel.Size = New-Object System.Drawing.Size(280,20) 
  
$objLabel.Text = "Please enter the username you'd like to restore below:"  
$objForm.Controls.Add($objLabel) 
  
  
$objTextBox = New-Object System.Windows.Forms.TextBox 
$objTextBox.Location = New-Object System.Drawing.Size(10,40)   
$objTextBox.Size = New-Object System.Drawing.Size(260,20)   
$objForm.Controls.Add($objTextBox) 
  
 
  
$objForm.Topmost = $True
  
   
$objForm.Add_Shown({$objForm.Activate()})  
[void] $objForm.ShowDialog()
  
 
#$x variable is passed to powershell cmdlets below
$x
  
#imports active directory module to run AD cmdlets
Import-Module activedirectory
  
#searches AD for object stored in variable by samaccount name and restores it 
get-adobject -filter {samaccountname -eq $x } -includedeletedobjects | restore-adobject
  
 
  
   


This is really a very simple script.  95% of it is just the code required to construct the form.  Let me know if you have any questions.


Disclaimer: All scripts and other powershell references on this blog are offered "as is" with no warranty.  While these scripts are tested and working in my environment, it is recommended that you test these scripts in a test environment before using in your production environment.


Monday, July 16, 2012

Active Directory: User Password Expiration Notice

Active directory password expiration notifications that are built in can be easy to missed by users.  They occasionally show up as a bubble in the notification area on your desktop which are easily overlooked.  They also show up in Outlook web access as a little gold bar that blends in too well with its surroundings and is also often overlooked. 

The script below will provide you with an email message that tells you how many days until  your password expires.  You can configure this to run how ever many days in advance that you want by changing the numbers in the "if statements".  You will want to configure the number in parenthesis in the $passexpirationdate variable per your domain password policy.  If you don't know your max password age you can easily view it by running the following commands in powershell:

Import-Module ActiveDirectory
  
Get-ADDefaultDomainPasswordPolicy  

Set it up as a scheduled task to run daily and it will continue to email your users until they change their password.  Here's the script with comments on what each portion does.  Save it as password_exp_notice.ps1:


 ##############################################################################################
  
 #           Password Expiration Notification 
 # 
 # This script is designed to notify users via email of an upcoming password change. 
 # This script requires your forest and domain functional level to be 2008 R2. 
 # You must have active directory client tools installed to run this or run it from a DC.
 #
 # Source: ps1scripting.blogspot.com
 # 
 #
##############################################################################################
  
 
  
 #Loads the active directory module to enable AD cmdlets 
 import-module activedirectory
  
 
 #Queries all accounts in AD domain and stores them in username variable 
 $username = get-aduser -filter * | select -ExpandProperty samaccountname
  

 #Foreach loop is run against each account stored in the username variable 
 foreach($user in $username){
  
   #gets current date and stores in now variable
   $now = get-date
  
   #gets date of when password was last set for a user
   $passlastset = get-aduser $user -properties passwordlastset | select -ExpandProperty passwordlastset
  
 
  
   #calculates password expirationdate by adding 60 days to the password last set date
   $passexpirationdate = $passlastset.adddays(60)
  
 
  
   #calculates the number of days until a user's password will expire
   $daystilexpire = $passexpirationdate - $now | select -ExpandProperty days
  
 
  
     #if statement to select only accounts with expiration greater than 0 days
     if($daystilexpire -gt "0"){
  
  
       #if statment to further filter accounts from above if statement. This selects accounts with less than 5 days until expiration.
       if($daystilexpire -le "5"){
  
 
  
         #generates email to user using .net smtpclient to notify them of how many days until their password expires.
         $emailFrom = "emailaddress@yourdomain.com"
         $emailTo = "$user@yourdomain.com"
         $subject = "Password Expiration Notice"
         $body = "Your password will expire in $daystilexpire days. Please change your password soon to avoid being locked out of your account."
         $smtpServer = "Enter IP address of your SMTP Server Here"
         $smtp = new-object Net.Mail.SmtpClient($smtpServer)
         $smtp.Send($emailFrom, $emailTo, $subject, $body)
  
  
       }
      }
   }
  
   


There it is.  A quick easy script that is sure to save you several calls about account expirations.  Feel free to leave comments, questions, or ideas for improvement.  Thanks for reading.

Disclaimer: All scripts and other powershell references on this blog are offered "as is" with no warranty.  While these scripts are tested and working in my environment, it is recommended that you test these scripts in a test environment before using in your production environment.

Sunday, July 15, 2012

Powershell: Scratching the Surface

Powershell: Scratching the Surface


I started using powershell a few years back to automate the creation of Exchange emailboxes in our Exchange 2007 system.  I used some borrowed code and modified it to fit our environment.  At the time I was able to figure it out just good enough to get it working.  I've since made a lot of progess with learning the scripting language and have not found many things I can't do with it.  If you are familiar with writing cmd batch files, this should come fairly easy to you.

Powershell to me seemed a bit intimidating at first because of the complexity the cmdlets could reach.  I've since learned that it is very easy to use once you understand some of the base concepts.  About a year ago, I was determined to learn more about it and have progressed greatly in my ability to write scripts.  I've found a lot of help out there from numerous online resources and would like to pull what I know into this blog to help others get started.  I'll start with some basics here and work my way into some more advanced scripts.  

Example 1: Simple text output


For starters, lets do some "Hello World" examples.  This first example is how you can simply output the text "Hello World" in the command shell window.

write-host "Hello World"

This is as simple as it gets.  Notice that the command write-host is a verb-noun combination that produces a result.  Most powershell cmdlets revolve around this concept, which to me makes it much easier to remember commands.  A lot of powershell commands have a shorter equivelent command.  For example:

Echo "Hello World"

Echo, which you remember from DOS and cmd prompt produces the same result as write-host.  Another example:

get-childitem

dir

Some cmdlets also have short acronyms you can use instead of typing the full command such as:

gci

Gci will give you the same directory listing output as get-childitem or dir. 

Anyway, back to hello world.  So say you want to output a string of text to a file to store for later use or review.  You can accomplish this in this way:

echo "Hello World" | out-file c:\scripts\helloworld.txt

You can append text to that same file this way:

echo "Hello World" | out-file c:\scripts\helloworld.txt -append

In some cases you may run into a program that isn't able to properly decode the default encoding scheme.  Let's set the encoding to ascii by doing this:

echo "Hello World" | out-file -encoding ascii c:\scripts\helloworld.txt -append

Now, lets say you want to read the text from the helloworld.txt file you just created.  You can accomplish this by doing the following:

get-content c:\scripts\helloworld.txt

This will display the contents of the helloworld.txt file in the powershell console.

Example 2: Simple Variable Usage

Learning the ins and outs of variable usage in powershell is very important because you'll use them in almost every script you write.  All powershell variables are preceeded by a $ and are connected to a value using a  = .  For example:

$value1 = 5
$value2 = 7

Powershell is also equiped with mathematical functionality.  After creating the variables above, try this:

$value1 + $value2

You should see an output of "12" on your screen as powershell performed an addition function in this last command.

Here's another way you can use variables to store a value.  Lets pull the data from the helloworld.txt we created in the last example.

$hello = get-content "c:\scripts\helloworld.txt"

Now that we've stored the contents of the text file in the variable, lets run it by typing the following:

$hello

This displays the contents of the text file in the console.

Lets combine this with some other text.  Type the following:

write-host "$hello, how are you?"

Now you have combined the contents of the text file with the additional provided text to create a single output in the console.

This concludes my first post.  Hope it was helpful.  For questions or comments, please email ps1scripting@gmail.com