<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Practical PowerShell Magic for Exchange Online</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/exoshellwizard/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/exoshellwizard/feed.xml</link>
    <description>Level up with Exchange Online and PowerShell</description>
    <lastBuildDate>Wed, 17 Apr 2019 03:26:34 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Scheduling a task against Exchange Online</title>
      <link>https://docs.microsoft.com/archive/blogs/exoshellwizard/scheduling-a-task-against-exchange-online</link>
      <pubDate>Thu, 12 May 2016 14:30:18 GMT</pubDate>
      <dc:creator><![CDATA[Canthv0]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/exoshellwizard/?p=35</guid>
      <description><![CDATA[A request that customers ask us with some regularity in Exchange Online support is how do I automate...]]></description>
      <content:encoded><![CDATA[A request that customers ask us with some regularity in Exchange Online support is how do I automate tasks against Exchange Online.  Customer are used to their on premise environment where they can regularly run reports on all sorts of information and they want at least some of that in Exchange Online.

The method I am going to highlight today is using a local server (any server) to run a Scheduled Task that will connect to Exchange Online and retrieve some mailbox statistics information.  This is a nice basic implementation that can easily be expanded on.
<h3><!--more-->What we will need:</h3>
<ul>
	<li style="padding-left: 30px">Server that is always online</li>
	<li style="padding-left: 30px">Set of logon credentials for that server</li>
	<li style="padding-left: 30px">Set of EXO credentials that can run our script (Recommend different from your main admin account)</li>
	<li style="padding-left: 30px">Scripts listed below</li>
</ul>
<h3>Implementation time:</h3>
30 Minutes
<h3>Directions:</h3>
For this set of directions I am going to walk you thru setting up and running the script using <code>Start-AutomatedBasicScript.ps1</code> this is just a simple easy to understand example that will establish a session to O365 and get the Mailbox Statistics for all users listed in recipients.csv.
<h4>Prepare the needed inputs:</h4>
<ol>
	<li>Log into a server</li>
	<li>Create a directory to store the scripts and output ( <code>C:\Scripts</code> )</li>
	<li>Copy and save off the three scripts below into your path</li>
	<li><a title="Connect to Exchange Online using remote PowerShell" href="https://technet.microsoft.com/en-us/library/jj984289(v=exchg.160).aspx">Connect to Exchange Online PowerShell </a></li>
	<li>Get the recipients we want to get a report on
<code>Get-Mailbox -resultsize 100| select-object -property PrimarySMTPAddress | export-csv c:\scripts\recipients.csv</code></li>
	<li>Run the New-StoredCredential.ps1 script
<ol>
	<li>Start Powershell</li>
	<li>Change to your directory</li>
	<li>Run <code>.\New-StoredCredential.ps1 -Path c:\scripts\O365Account.txt -Password "&lt;your password&gt;"</code></li>
</ol>
</li>
</ol>
<h4>Create the scheduled task:</h4>
<ol>
	<li>Start Task Scheduler</li>
	<li>Create a new <a title="Basic Link" href="https://technet.microsoft.com/en-us/library/cc748993.aspx">Basic Task</a></li>
	<li>Name it</li>
	<li>Schedule it for One Time (I usually do 10 min in the past)</li>
	<li>Choose to have it start a program</li>
	<li>Put <code>powershell.exe</code> as the program to run</li>
	<li>The arguments should be <code>-noprofile -file c:\scripts\Start-AutomatedBasicScript.ps1</code></li>
	<li>Make sure to choose "Open the properties dialog for this task when I click Finish" then finish creating the task</li>
	<li>On the properties page we want to change two options
<ol>
	<li>Select "Run whether user is logged on or not"</li>
	<li>Select "Do not store password"</li>
</ol>
</li>
</ol>
<h3>Testing:</h3>
To run the script for testing simply right click your task and choose "Run Now".  You won't see any thing pop up but if you refresh the Task Scheduler it will show when the task has completed.

If you have the expected output in c:\scripts\outputXXX.csv then everything worked.  If you don't then we can make some simple changes to try and figure out what is happening.
<h4>Option 1: Watch the script</h4>
<ol>
	<li>Bring up the properties of the scheduled task.</li>
	<li>Change from "Run whether user is logged on or not" to "Run only when user is logged on"</li>
</ol>
Now when you click "Run Now" the PowerShell window will appear and you can watch the script execute.
<h4>Option 2: Get a transcript</h4>
Add the following line at the top of your script.<code>
</code>

<code>Start-Transcript -path c:\scripts</code>

Review the transcript that is created to determine what happened during the script run.
<h3>Additional Resources:</h3>
<a href="https://blogs.technet.microsoft.com/exchange/2015/11/02/running-powershell-cmdlets-for-large-numbers-of-users-in-office-365/"><script src="https://www.google-analytics.com/plugins/ga/inpage_linkid.js" type="text/javascript"></script><script src="https://ssl.google-analytics.com/ga.js" type="text/javascript"></script><script src="https://code.jquery.com/jquery-1.11.3.min.js" type="text/javascript"></script><script src="https://blogs.technet.microsoft.com/exchange/wp-content/plugins/simple-follow-me-social-buttons-widget/assets/js/front-widget.js?ver=3.3.3" type="text/javascript"></script><script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js" type="text/javascript"></script><script src="https://blogs.technet.microsoft.com/exchange/wp-content/themes/microsoft/js/single.js?ver=05052016" type="text/javascript"></script><script src="https://blogs.technet.microsoft.com/exchange/wp-content/themes/microsoft/js/social-counts.js?ver=05052016" type="text/javascript"></script><script type="text/javascript">// </script>Running PowerShell cmdlets for large numbers of users in Office 365</a> - Very useful script for operating on thousands of Objects in Exchange Online in a robust manner.
<h3>Scripts:</h3>
*** All scripts/code shown here are covered by the standard disclaimer listed <a title="Alakazam" href="https://blogs.technet.microsoft.com/exoshellwizard/2016/05/12/alakazam/">here</a>. ***

<strong>New-StoredCredential.ps1</strong>
Copy the below script into a notepad document.
Save the document as New-StoredCredential.ps1
<pre><!-- Code highlighting produced by Actipro SyntaxEditor https://www.ActiproSoftware.com/Products/DotNet/ --><span style="color: #0000ff">param</span><span style="color: #000000">(
    [Parameter(Mandatory</span><span style="color: #ff0000">=</span><span style="color: #800080">$true</span><span style="color: #000000">)]
    [</span><span style="color: #008080">string</span><span style="color: #000000">]</span><span style="color: #800080">$Path</span><span style="color: #000000">,
    [Parameter(Mandatory</span><span style="color: #ff0000">=</span><span style="color: #800080">$true</span><span style="color: #000000">)]
    [</span><span style="color: #008080">string</span><span style="color: #000000">]</span><span style="color: #800080">$password</span><span style="color: #000000">
    )

    </span><span style="color: #008000">#</span><span style="color: #008000"> Convert the password to a secure string</span>
    <span style="color: #800080">$SecurePassword</span> <span style="color: #ff0000">=</span> <span style="color: #800080">$password</span><span style="color: #000000"> | </span><span style="color: #5f9ea0;font-weight: bold">ConvertTo-SecureString</span> <span style="color: #5f9ea0;font-style: italic">-AsPlainText</span> <span style="color: #5f9ea0;font-style: italic">-Force</span>
    
    <span style="color: #008000">#</span><span style="color: #008000"> Store the credential in the path</span>
    <span style="color: #800080">$SecurePassword</span><span style="color: #000000"> | </span><span style="color: #5f9ea0;font-weight: bold">ConvertFrom-SecureString</span><span style="color: #000000"> | </span><span style="color: #5f9ea0;font-weight: bold">Out-File</span> <span style="color: #800080">$Path</span>
    
    <span style="color: #008000">#</span><span style="color: #008000"> Write What we did</span>
    <span style="color: #5f9ea0;font-weight: bold">Write-Host</span> <span style="color: #800000">"</span><span style="color: #800000">Wrote password to $path</span><span style="color: #800000">"</span>    
    
<span style="color: #008000">&lt;#</span><span style="color: #008000"> 
.SYNOPSIS
Stores a password in a file on the local computer for retrevial by scripts.

.DESCRIPTION
Used for securely storing a password on a machine for use with automated scripts.

Takes a password and encrypts it using the local account, then stores that password in a file you specify.
Only the account that creates the output file can decrypt the password stored in the file.

.PARAMETER Path
Path and file name for the password file that will be created.

.PARAMETER Password
Plain text version of password.

.OUTPUTS
File Specified in Path variable will contain an encrypted version of the password.

.EXAMPLE
.\New-StoredCredential.ps1 -Path c:\scripts\O365Account.txt -Password "Password123"

Puts the encrypted version of Password123 into the c:\scripts\O365Account.txt file
</span><span style="color: #008000">#&gt;
</span></pre>
<strong>Start-AutomatedBasicScript.ps1
</strong>Copy the below script into a notepad document.
Save the document as Start-AutomatedBasicScript.ps1
<pre><!-- Code highlighting produced by Actipro SyntaxEditor https://www.ActiproSoftware.com/Products/DotNet/ --><span style="color: #008000">#</span><span style="color: #008000"> Constants</span>
<span style="color: #000000">[</span><span style="color: #008080">string</span><span style="color: #000000">]</span><span style="color: #800080">$FileAppend</span> <span style="color: #ff0000">=</span><span style="color: #000000"> (</span><span style="color: #5f9ea0;font-weight: bold">Get-Date</span> <span style="color: #5f9ea0;font-style: italic">-Format</span> <span style="color: #800000">mmddyyyy_</span><span style="color: #000000">) </span><span style="color: #ff0000">+</span><span style="color: #000000"> (</span><span style="color: #5f9ea0;font-weight: bold">Get-Random</span> <span style="color: #5f9ea0;font-style: italic">-Maximum</span> <span style="color: #000000">9999</span><span style="color: #000000">)
</span><span style="color: #800080">$OutputFile</span> <span style="color: #ff0000">=</span> <span style="color: #800000">"</span><span style="color: #800000">C:\scripts\output</span><span style="color: #800000">"</span> <span style="color: #ff0000">+</span> <span style="color: #800080">$FileAppend</span> <span style="color: #ff0000">+</span> <span style="color: #800000">"</span><span style="color: #800000">.csv</span><span style="color: #800000">"</span>
<span style="color: #800080">$Username</span> <span style="color: #ff0000">=</span> <span style="color: #800000">"</span><span style="color: #800000">admin@company.onmicrosoft.com</span><span style="color: #800000">"</span>
<span style="color: #800080">$RecipientCSV</span> <span style="color: #ff0000">=</span> <span style="color: #800000">"</span><span style="color: #800000">c:\scripts\recipients.csv</span><span style="color: #800000">"</span>
<span style="color: #800080">$PasswordPath</span> <span style="color: #ff0000">=</span> <span style="color: #800000">"</span><span style="color: #800000">c:\scripts\password.txt</span><span style="color: #800000">"</span>

<span style="color: #008000">#</span><span style="color: #008000"> Read the password from the file and convert to SecureString</span>
<span style="color: #5f9ea0;font-weight: bold">Write-Host</span> <span style="color: #800000">"</span><span style="color: #800000">Getting password from $passwordpath</span><span style="color: #800000">"</span>
<span style="color: #800080">$SecurePassword</span> <span style="color: #ff0000">=</span> <span style="color: #5f9ea0;font-weight: bold">Get-Content</span> <span style="color: #800080">$PasswordPath</span><span style="color: #000000"> | </span><span style="color: #5f9ea0;font-weight: bold">ConvertTo-SecureString</span>

<span style="color: #008000">#</span><span style="color: #008000"> Build a Credential Object from the password file and the $username constant</span>
<span style="color: #800080">$Credential</span> <span style="color: #ff0000">=</span> <span style="color: #5f9ea0;font-weight: bold">New-Object</span> <span style="color: #800000">System.Management.Automation.PSCredential</span> <span style="color: #5f9ea0;font-style: italic">-ArgumentList</span> <span style="color: #800080">$Username</span><span style="color: #000000">, </span><span style="color: #800080">$SecurePassword</span>

<span style="color: #008000">#</span><span style="color: #008000"> Open a session to O365</span>
<span style="color: #800080">$O365Session</span> <span style="color: #ff0000">=</span> <span style="color: #5f9ea0;font-weight: bold">New-PSSession</span> <span style="color: #5f9ea0;font-style: italic">-ConfigurationName</span> <span style="color: #800000">Microsoft.Exchange</span> <span style="color: #5f9ea0;font-style: italic">-ConnectionUri</span><span style="color: #000000"> https://</span><span style="color: #800000">outlook.office365.com</span><span style="color: #000000">/powershell-liveid</span><span style="color: #800000">/</span> <span style="color: #5f9ea0;font-style: italic">-Credential</span> <span style="color: #800080">$Credential</span> <span style="color: #5f9ea0;font-style: italic">-Authentication</span> <span style="color: #800000">Basic</span> <span style="color: #5f9ea0;font-style: italic">-AllowRedirection</span>
<span style="color: #5f9ea0;font-weight: bold">import-pssession</span> <span style="color: #800080">$O365session</span>

<span style="color: #008000">#</span><span style="color: #008000"> Get the Recipients to work with</span>
<span style="color: #800080">$Recipients</span> <span style="color: #ff0000">=</span> <span style="color: #5f9ea0;font-weight: bold">Import-Csv</span> <span style="color: #800080">$RecipientCSV</span>

<span style="color: #008000">#</span><span style="color: #008000"> Get the Mailbox Statistics</span>
<span style="color: #800080">$Recipients</span><span style="color: #000000"> | </span><span style="color: #5f9ea0;font-weight: bold">Foreach</span><span style="color: #000000"> {
    Get-Mailboxstatistics -Identity </span><span style="color: #800080">$_</span><span style="color: #000000">.primarysmtpaddress.tostring() | </span><span style="color: #5f9ea0;font-weight: bold">Select-Object</span><span style="color: #000000"> Identity,DeletedItemCount,TotalDeletedItemSize,TotalItemSize | </span><span style="color: #5f9ea0;font-weight: bold">Export-Csv</span> <span style="color: #800080">$OutputFile</span> <span style="color: #5f9ea0;font-style: italic">-Append</span><span style="color: #000000"> 
}

</span><span style="color: #008000">&lt;#</span><span style="color: #008000"> 
.SYNOPSIS
Simple Example Script that can be run in an automated manner against Exchange Online

.DESCRIPTION
Simple Example script for runing an automated task against Exchange Online.
     * All output/input files are defined in the #Constatns section
     * Connects to O365 using password stored on the local machine
     * Imports list of recipients from a CSV file
     * Get Mailbox Statistics information and exports to CSV

.INPUTS
recipients.csv - Csv of recipients to gather data on expected to include PrimarySMTPAddress property
password.txt   - Encrypted password for O365 account you can use New-StoredCredentials.ps1 to create this file

.OUTPUTS
A CSV file with the requested mailbox statistics information.  Will be stamped with the date and a random number to make it unique. 

.EXAMPLE
.\Start-AutomatedBasicScript.ps1

</span><span style="color: #008000">#&gt;</span></pre>
<strong>Start-AutomatedScript.ps1</strong>
Copy the below script into a notepad document.
Save the document as Start-AutomatedScript.ps1
<pre><!-- Code highlighting produced by Actipro SyntaxEditor https://www.ActiproSoftware.com/Products/DotNet/ --><span style="color: #008000">#</span><span style="color: #008000"> Constants</span>
<span style="color: #000000">[</span><span style="color: #008080">string</span><span style="color: #000000">]</span><span style="color: #800080">$FileAppend</span> <span style="color: #ff0000">=</span><span style="color: #000000"> (</span><span style="color: #5f9ea0;font-weight: bold">Get-Date</span> <span style="color: #5f9ea0;font-style: italic">-Format</span> <span style="color: #800000">mmddyyyy_</span><span style="color: #000000">) </span><span style="color: #ff0000">+</span><span style="color: #000000"> (</span><span style="color: #5f9ea0;font-weight: bold">Get-Random</span> <span style="color: #5f9ea0;font-style: italic">-Maximum</span> <span style="color: #000000">9999</span><span style="color: #000000">)
</span><span style="color: #800080">$OutputFile</span> <span style="color: #ff0000">=</span> <span style="color: #800000">"</span><span style="color: #800000">C:\scripts\output</span><span style="color: #800000">"</span> <span style="color: #ff0000">+</span> <span style="color: #800080">$FileAppend</span> <span style="color: #ff0000">+</span> <span style="color: #800000">"</span><span style="color: #800000">.csv</span><span style="color: #800000">"</span>
<span style="color: #800080">$Username</span> <span style="color: #ff0000">=</span> <span style="color: #800000">"</span><span style="color: #800000">admin@contoso.onmicrosoft.com</span><span style="color: #800000">"</span>
<span style="color: #800080">$LogFile</span> <span style="color: #ff0000">=</span> <span style="color: #800000">"</span><span style="color: #800000">C:\scripts\testing.log</span><span style="color: #800000">"</span>
<span style="color: #800080">$ExportRecipients</span> <span style="color: #ff0000">=</span> <span style="color: #800000">"</span><span style="color: #800000">c:\scripts\recipients.csv</span><span style="color: #800000">"</span>
<span style="color: #800080">$PasswordPath</span> <span style="color: #ff0000">=</span> <span style="color: #800000">"</span><span style="color: #800000">c:\scripts\password.txt</span><span style="color: #800000">"</span>


<span style="color: #008000">#</span><span style="color: #008000"> Writes output to a log file with a time date stamp</span>
<span style="color: #0000ff">Function</span> <span style="color: #5f9ea0">Write-Log</span><span style="color: #000000"> {
    </span><span style="color: #0000ff">Param</span><span style="color: #000000"> ([</span><span style="color: #008080">string</span><span style="color: #000000">]</span><span style="color: #800080">$string</span><span style="color: #000000">)
    
    </span><span style="color: #008000">#</span><span style="color: #008000"> Get the current date</span>
<span style="color: #000000">    [</span><span style="color: #008080">string</span><span style="color: #000000">]</span><span style="color: #800080">$date</span> <span style="color: #ff0000">=</span> <span style="color: #5f9ea0;font-weight: bold">Get-Date</span> <span style="color: #5f9ea0;font-style: italic">-Format</span> <span style="color: #800000">G</span>
        
    <span style="color: #008000">#</span><span style="color: #008000"> Write everything to our log file</span>
<span style="color: #000000">    ( </span><span style="color: #800000">"</span><span style="color: #800000">[</span><span style="color: #800000">"</span> <span style="color: #ff0000">+</span> <span style="color: #800080">$date</span> <span style="color: #ff0000">+</span> <span style="color: #800000">"</span><span style="color: #800000">] - </span><span style="color: #800000">"</span> <span style="color: #ff0000">+</span> <span style="color: #800080">$string</span><span style="color: #000000">) | </span><span style="color: #5f9ea0;font-weight: bold">Out-File</span> <span style="color: #5f9ea0;font-style: italic">-FilePath</span> <span style="color: #800080">$LogFile</span> <span style="color: #5f9ea0;font-style: italic">-Append</span>
    
    <span style="color: #008000">#</span><span style="color: #008000"> If NonInteractive true then supress host output</span>
    <span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #ff0000">!</span><span style="color: #000000">(</span><span style="color: #800080">$NonInteractive</span><span style="color: #000000">)){
        ( </span><span style="color: #800000">"</span><span style="color: #800000">[</span><span style="color: #800000">"</span> <span style="color: #ff0000">+</span> <span style="color: #800080">$date</span> <span style="color: #ff0000">+</span> <span style="color: #800000">"</span><span style="color: #800000">] - </span><span style="color: #800000">"</span> <span style="color: #ff0000">+</span> <span style="color: #800080">$string</span><span style="color: #000000">) | </span><span style="color: #5f9ea0;font-weight: bold">Write-Host</span><span style="color: #000000">
    }
}

</span><span style="color: #008000">#</span><span style="color: #008000"> Setup a new O365 Powershell Session</span>
<span style="color: #0000ff">Function</span> <span style="color: #5f9ea0">New-CleanO365Session</span><span style="color: #000000"> {
    
    </span><span style="color: #008000">#</span><span style="color: #008000"> If we don't have a credential then prompt for it</span>
    <span style="color: #800080">$i</span> <span style="color: #ff0000">=</span> <span style="color: #000000">0</span>
    <span style="color: #0000ff">while</span><span style="color: #000000"> ((</span><span style="color: #800080">$Credential</span> <span style="color: #ff0000">-eq</span> <span style="color: #800080">$Null</span><span style="color: #000000">) </span><span style="color: #ff0000">-and</span><span style="color: #000000"> (</span><span style="color: #800080">$i</span> <span style="color: #ff0000">-lt</span> <span style="color: #000000">5</span><span style="color: #000000">)){
        </span><span style="color: #800080">$script:Credential</span> <span style="color: #ff0000">=</span> <span style="color: #5f9ea0;font-weight: bold">Get-Credential</span> <span style="color: #5f9ea0;font-style: italic">-Message</span> <span style="color: #800000">"</span><span style="color: #800000">Please provide your Exchange Online Credentials</span><span style="color: #800000">"</span>
        <span style="color: #800080">$i</span><span style="color: #ff0000">++</span><span style="color: #000000">
    }
    
    </span><span style="color: #008000">#</span><span style="color: #008000"> If we still don't have a credentail object then abort</span>
    <span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #800080">$Credential</span> <span style="color: #ff0000">-eq</span> <span style="color: #800080">$null</span><span style="color: #000000">){
        </span><span style="color: #5f9ea0">Write-log</span> <span style="color: #800000">"</span><span style="color: #800000">[Error] - Failed to get credentials</span><span style="color: #800000">"</span>
        <span style="color: #5f9ea0;font-weight: bold">Write-Error</span> <span style="color: #5f9ea0;font-style: italic">-Message</span> <span style="color: #800000">"</span><span style="color: #800000">Failed to get credentials</span><span style="color: #800000">"</span> <span style="color: #5f9ea0;font-style: italic">-ErrorAction</span> <span style="color: #800000">Stop</span><span style="color: #000000">
    }

    </span><span style="color: #5f9ea0">Write-Log</span> <span style="color: #800000">"</span><span style="color: #800000">Removing all PS Sessions</span><span style="color: #800000">"</span>

    <span style="color: #008000">#</span><span style="color: #008000"> Destroy any outstanding PS Session</span>
    <span style="color: #5f9ea0;font-weight: bold">Get-PSSession</span><span style="color: #000000"> | </span><span style="color: #5f9ea0;font-weight: bold">Remove-PSSession</span> <span style="color: #5f9ea0;font-style: italic">-Confirm</span><span style="color: #000000">:</span><span style="color: #800080">$false</span>
    
    <span style="color: #008000">#</span><span style="color: #008000"> Force Garbage collection just to try and keep things more agressively cleaned up due to some issue with large memory footprints</span>
<span style="color: #000000">    [</span><span style="color: #008080">System.GC</span><span style="color: #000000">]::</span><span style="color: #8b4513">Collect</span><span style="color: #000000">()
    
    </span><span style="color: #008000">#</span><span style="color: #008000"> Sleep 15s to allow the sessions to tear down fully</span>
    <span style="color: #5f9ea0">Write-Log</span><span style="color: #000000"> (</span><span style="color: #800000">"</span><span style="color: #800000">Sleeping 15 seconds for Session Tear Down</span><span style="color: #800000">"</span><span style="color: #000000">)
    </span><span style="color: #5f9ea0;font-weight: bold">Start-sleep</span> <span style="color: #5f9ea0;font-style: italic">-seconds</span> <span style="color: #000000">15</span>

    <span style="color: #008000">#</span><span style="color: #008000"> Clear out all errors</span>
    <span style="color: #800080">$Error</span><span style="color: #000000">.</span><span style="color: #8b4513">Clear</span><span style="color: #000000">()
    
    </span><span style="color: #008000">#</span><span style="color: #008000"> Create the session</span>
    <span style="color: #5f9ea0">Write-Log</span> <span style="color: #800000">"</span><span style="color: #800000">Creating new PS Session</span><span style="color: #800000">"</span>
    
    <span style="color: #800080">$session</span> <span style="color: #ff0000">=</span> <span style="color: #5f9ea0;font-weight: bold">New-PSSession</span> <span style="color: #5f9ea0;font-style: italic">-ConfigurationName</span> <span style="color: #800000">Microsoft.Exchange</span> <span style="color: #5f9ea0;font-style: italic">-ConnectionUri</span> <span style="color: #800000">"</span><span style="color: #800000">https://outlook.office365.com/powershell-liveid/</span><span style="color: #800000">"</span> <span style="color: #5f9ea0;font-style: italic">-Credential</span> <span style="color: #800080">$Credential</span> <span style="color: #5f9ea0;font-style: italic">-Authentication</span> <span style="color: #800000">Basic</span> <span style="color: #5f9ea0;font-style: italic">-AllowRedirection</span>
        
    <span style="color: #008000">#</span><span style="color: #008000"> Check for an error while creating the session</span>
    <span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #800080">$Error</span><span style="color: #000000">.</span><span style="color: #8b4513">Count</span> <span style="color: #ff0000">-gt</span> <span style="color: #000000">0</span><span style="color: #000000">){
    
        </span><span style="color: #5f9ea0">Write-Log</span> <span style="color: #800000">"</span><span style="color: #800000">[ERROR] - Error while setting up session</span><span style="color: #800000">"</span>
        <span style="color: #5f9ea0">Write-log</span> <span style="color: #800080">$Error</span>
        
        <span style="color: #008000">#</span><span style="color: #008000"> Increment our error count so we abort after so many attempts to set up the session</span>
        <span style="color: #800080">$ErrorCount</span><span style="color: #ff0000">++</span>
        
        <span style="color: #008000">#</span><span style="color: #008000"> if we have failed to setup the session &gt; 3 times then we need to abort because we are in a failure state</span>
        <span style="color: #0000ff">if</span><span style="color: #000000"> (</span><span style="color: #800080">$ErrorCount</span> <span style="color: #ff0000">-gt</span> <span style="color: #000000">3</span><span style="color: #000000">){
        
            </span><span style="color: #5f9ea0">Write-log</span> <span style="color: #800000">"</span><span style="color: #800000">[ERROR] - Failed to setup session after multiple tries</span><span style="color: #800000">"</span>
            <span style="color: #5f9ea0">Write-log</span> <span style="color: #800000">"</span><span style="color: #800000">[ERROR] - Aborting Script</span><span style="color: #800000">"</span><span style="color: #000000">
            exit
        
        }
        
        </span><span style="color: #008000">#</span><span style="color: #008000"> If we are not aborting then sleep 60s in the hope that the issue is transient</span>
        <span style="color: #5f9ea0">Write-Log</span> <span style="color: #800000">"</span><span style="color: #800000">Sleeping 60s so that issue can potentially be resolved</span><span style="color: #800000">"</span>
        <span style="color: #5f9ea0;font-weight: bold">Start-sleep</span> <span style="color: #5f9ea0;font-style: italic">-seconds</span> <span style="color: #000000">60</span>
        
        <span style="color: #008000">#</span><span style="color: #008000"> Attempt to set up the sesion again</span>
        <span style="color: #5f9ea0">New-CleanO365Session</span><span style="color: #000000">
    }
    
    </span><span style="color: #008000">#</span><span style="color: #008000"> If the session setup worked then we need to set $errorcount to 0</span>
    <span style="color: #0000ff">else</span><span style="color: #000000"> {
        </span><span style="color: #800080">$ErrorCount</span> <span style="color: #ff0000">=</span> <span style="color: #000000">0</span><span style="color: #000000">
    }
    
    </span><span style="color: #008000">#</span><span style="color: #008000"> Import the PS session</span>
    <span style="color: #800080">$null</span> <span style="color: #ff0000">=</span> <span style="color: #5f9ea0;font-weight: bold">Import-PSSession</span> <span style="color: #800080">$session</span> <span style="color: #5f9ea0;font-style: italic">-AllowClobber</span>
    
    <span style="color: #008000">#</span><span style="color: #008000"> Set the Start time for the current session</span>
    <span style="color: #5f9ea0;font-weight: bold">Set-Variable</span> <span style="color: #5f9ea0;font-style: italic">-Scope</span> <span style="color: #800000">script</span> <span style="color: #5f9ea0;font-style: italic">-Name</span> <span style="color: #800000">SessionStartTime</span> <span style="color: #5f9ea0;font-style: italic">-Value</span><span style="color: #000000"> (</span><span style="color: #5f9ea0;font-weight: bold">Get-Date</span><span style="color: #000000">)
}

</span><span style="color: #008000">#</span><span style="color: #008000">#### Main #####</span>

<span style="color: #008000">#</span><span style="color: #008000"> Read the password from the file and convert to SecureString</span>
<span style="color: #5f9ea0">Write-log</span> <span style="color: #800000">"</span><span style="color: #800000">Getting password from $passwordpath</span><span style="color: #800000">"</span>
<span style="color: #800080">$SecurePassword</span> <span style="color: #ff0000">=</span> <span style="color: #5f9ea0;font-weight: bold">Get-Content</span> <span style="color: #800080">$PasswordPath</span><span style="color: #000000"> | </span><span style="color: #5f9ea0;font-weight: bold">ConvertTo-SecureString</span>

<span style="color: #008000">#</span><span style="color: #008000"> Build a Credential Object from the password file and the $username constant</span>
<span style="color: #800080">$Credential</span> <span style="color: #ff0000">=</span> <span style="color: #5f9ea0;font-weight: bold">New-Object</span> <span style="color: #800000">System.Management.Automation.PSCredential</span> <span style="color: #5f9ea0;font-style: italic">-ArgumentList</span> <span style="color: #800080">$Username</span><span style="color: #000000">, </span><span style="color: #800080">$SecurePassword</span>

<span style="color: #008000">#</span><span style="color: #008000"> Connect to O365</span>
<span style="color: #5f9ea0">New-CleanO365Session</span>

<span style="color: #008000">#</span><span style="color: #008000"> Get the Recipients to work with</span>
<span style="color: #5f9ea0">Write-Log</span> <span style="color: #800000">"</span><span style="color: #800000">Getting Recipients</span><span style="color: #800000">"</span>
<span style="color: #800080">$Recipients</span> <span style="color: #ff0000">=</span> <span style="color: #5f9ea0;font-weight: bold">invoke-command</span> <span style="color: #5f9ea0;font-style: italic">-session</span><span style="color: #000000"> (</span><span style="color: #5f9ea0;font-weight: bold">get-pssession</span><span style="color: #000000">) </span><span style="color: #5f9ea0;font-style: italic">-scriptblock</span><span style="color: #000000"> {get-mailbox -resultsize unlimited | </span><span style="color: #5f9ea0;font-weight: bold">select-object</span> <span style="color: #5f9ea0;font-style: italic">-property</span><span style="color: #000000"> DisplayName,Identity,PrimarySMTPAddress}

</span><span style="color: #008000">#</span><span style="color: #008000"> Export them to CSV for documentation</span>
<span style="color: #5f9ea0">Write-Log</span> <span style="color: #800000">"</span><span style="color: #800000">Exporting </span><span style="color: #800000">"</span> <span style="color: #ff0000">+</span> <span style="color: #800080">$Recipients</span><span style="color: #000000">.count </span><span style="color: #ff0000">+</span> <span style="color: #800000">"</span><span style="color: #800000"> to csv </span><span style="color: #800000">"</span> <span style="color: #ff0000">+</span> <span style="color: #800080">$ExportRecipients</span>
<span style="color: #800080">$Recipients</span><span style="color: #000000"> | </span><span style="color: #5f9ea0;font-weight: bold">Export-Csv</span> <span style="color: #800080">$ExportRecipients</span>

<span style="color: #008000">#</span><span style="color: #008000"> Call Start-RobustCloudCommand to gather the data
# https://blogs.technet.microsoft.com/exchange/2015/11/02/running-powershell-cmdlets-for-large-numbers-of-users-in-office-365/</span>
<span style="color: #000000">C:\temp\Start-RobustCloudCommand.ps1 -Agree -LogFile </span><span style="color: #800080">$LogFile</span><span style="color: #000000"> -Recipients </span><span style="color: #800080">$Recipients</span><span style="color: #000000"> -ScriptBlock { Get-Mailboxstatistics -Identity </span><span style="color: #800080">$_</span><span style="color: #000000">.primarysmtpaddress.tostring() | </span><span style="color: #5f9ea0;font-weight: bold">Select-Object</span><span style="color: #000000"> Identity,DeletedItemCount,TotalDeletedItemSize,TotalItemSize | </span><span style="color: #5f9ea0;font-weight: bold">Export-Csv</span> <span style="color: #800080">$OutputFile</span> <span style="color: #5f9ea0;font-style: italic">-Append</span><span style="color: #000000"> } -Credential </span><span style="color: #800080">$Credential</span>

<span style="color: #008000">&lt;#</span><span style="color: #008000"> 
.SYNOPSIS
Example Script that can be run in an automated manner against Exchange Online

.DESCRIPTION
Example script for runing an automated task against Exchange Online.
     * All output/input files are defined in the #Constatns section
     * Connects to O365 using password stored on the local machine
     * Gets list of recipients from O365
     * Get Mailbox Statistics information and exports to CSV using a robust connection method

.OUTPUTS
A CSV file with the requested mailbox statistics information.  Will be stamped with the date and a random number to make it unique. 

.EXAMPLE
.\Start-AutomatedScript.ps1

</span><span style="color: #008000">#&gt;</span></pre>]]></content:encoded>
    </item>
    <item>
      <title>Alakazam</title>
      <link>https://docs.microsoft.com/archive/blogs/exoshellwizard/alakazam</link>
      <pubDate>Thu, 12 May 2016 14:24:49 GMT</pubDate>
      <dc:creator><![CDATA[Canthv0]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.technet.microsoft.com/exoshellwizard/?p=45</guid>
      <description><![CDATA[ALAKAZAM!
I have been doing Exchange support for Microsoft since June 2001.  When Exchange 2007...]]></description>
      <content:encoded><![CDATA[<h1 style="text-align: center">ALAKAZAM!</h1>
<p style="text-align: left">I have been doing Exchange support for Microsoft since June 2001.  When Exchange 2007 came out and we introduced this thing called PowerShell I dove right in.  Even wrote my first largish (100+ line) script before 2007 even shipped.</p>
<p style="text-align: left">Since then I have taken a practical approach to PowerShell focusing on fixing problems, filling deficits, and enabling something new.  With that in mind this blog is going to strive do the following things:</p>

<ul>
	<li style="text-align: left">Provide practical, useful PowerShell scripts that are well documented and clearly written</li>
	<li style="text-align: left">Provide them in "spell" format.  You will find this very similar to a cooking recipe where it is clear what you need, how long it will take, and how to do it.</li>
	<li style="text-align: left">Be reasonably responsive to feedback ... I do have a day job here ... :)</li>
</ul>
With all that being said please keep in mind that ALL scripts, code examples, etc. that you find here are implicitly posted here with the understanding that they are:
<pre>The sample scripts are not supported under any Microsoft standard support
program or service. The sample scripts are provided AS IS without warranty
of any kind. Microsoft further disclaims all implied warranties including, without
limitation, any implied warranties of merchantability or of fitness for a particular
purpose. The entire risk arising out of the use or performance of the sample scripts
and documentation remains with you. In no event shall Microsoft, its authors, or
anyone else involved in the creation, production, or delivery of the scripts be liable
for any damages whatsoever (including, without limitation, damages for loss of business
profits, business interruption, loss of business information, or other pecuniary loss)
arising out of the use of or inability to use the sample scripts or documentation,
even if Microsoft has been advised of the possibility of such damages.</pre>
<p style="text-align: left"> Otherwise I look forward to sharing all of the little solutions I have built up over the years.  If you have a question about a script, or a problem you think PowerShell could help you solve feel free to comment/ask, I will do my best to answer it, provide a solution, or point you at one.</p>
<p style="text-align: left">- Matt
- Resident PowerShell Wizard</p>]]></content:encoded>
    </item>
  </channel>
</rss>