<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>sidefumbling &#187; PowerShell</title>
	<atom:link href="http://www.flobee.net/category/scripts/powershell/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.flobee.net</link>
	<description>The consequence of not having six hydrocoptic marzelvanes.</description>
	<lastBuildDate>Tue, 24 Aug 2010 18:39:49 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Exchange 2010 prerequisite installation script updated</title>
		<link>http://www.flobee.net/exchange-2010-prerequisite-installation-script-updated-2/</link>
		<comments>http://www.flobee.net/exchange-2010-prerequisite-installation-script-updated-2/#comments</comments>
		<pubDate>Tue, 24 Aug 2010 18:37:33 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[Exchange 2010]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[inline code]]></category>

		<guid isPermaLink="false">http://www.flobee.net/?p=515</guid>
		<description><![CDATA[The installation script, originally referenced here, has been updated to version 1.5.  It adds support for installing just the management tools, including on Windows 7.  I was in the process of making it work on Vista as well, but it got messy because dism doesn&#8217;t come with Vista and I didn&#8217;t want to [...]]]></description>
			<content:encoded><![CDATA[<p>The installation script, originally referenced <a href="http://www.flobee.net/script-to-install-all-exchange-2010-prerequisites/">here</a>, has been updated to version 1.5.  It adds support for installing just the management tools, including on Windows 7.  I was in the process of making it work on Vista as well, but it got messy because dism doesn&#8217;t come with Vista and I didn&#8217;t want to have separate installation routines for Windows 7 and Vista.  So I am making the assumption that anyone who wants to install the management tools on a workstation has long given up on Vista.</p>
<p>To detect the OS (which is actually difficult and not uniform by any means) and make sure it is 64-bit, this sections is added:</p>
<pre class="brush:ps">
# Detect correct OS here and exit if no match
$wmiOS = Get-WMIObject win32_OperatingSystem
$OScap = $wmiOS.Caption
$OSver = $wmiOS.Version
[array]$wmiProc = Get-WmiObject win32_Processor
if ($wmiProc[0].Architecture -eq '9')
	{
	if ($OScap -match 'Windows 7')
		{$os = 'Win7'}
	elseif (($OSver -eq '6.1.7600') -and ($OScap -match '2008'))
		{$os = 'R2'}
	elseif ($OSver -eq '6.0.6002')
		{$os = 'R1'}
	else
...
</pre>
<p>Getting the processor as an array makes it work with both single and multi-processors.  As a reader kindly pointed out, when run on an R2 server, it kept thinking WinRM wasn&#8217;t installed.  This is because WinRM is preinstalled on R2 so the check for the hotfix KB installation will always fail.  It now skips the WinRM check for an R2 server.</p>
<p>I also updated the menu so you can select the management tools, and made it so you only are given the option of selecting the management tools when run on Windows 7.  (Only the menu reflects this restriction.  If you select a different option the script will still try and run that command.)  The download link is below.<br />
Note: There is a file embedded within this post, please visit this post to download the file.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.flobee.net/exchange-2010-prerequisite-installation-script-updated-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automatically disable ActiveSync for new mailboxes in Exchange 2010</title>
		<link>http://www.flobee.net/automatically-disable-activesync-for-new-mailboxes-in-exchange-2010/</link>
		<comments>http://www.flobee.net/automatically-disable-activesync-for-new-mailboxes-in-exchange-2010/#comments</comments>
		<pubDate>Wed, 30 Jun 2010 21:51:54 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[Exchange 2010]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[inline code]]></category>

		<guid isPermaLink="false">http://www.flobee.net/?p=510</guid>
		<description><![CDATA[One of the new features in Exchange 2010 is the use of cmdlet extension agents, as described in this post.  Using the Scripting Agent you can have Exchange ActiveSync disabled whenever a mailbox is created for a new or existing user.  This removes the need to do it directly against Active Directory through [...]]]></description>
			<content:encoded><![CDATA[<p>One of the new features in Exchange 2010 is the use of cmdlet extension agents, as described in <a href="http://www.ucblogs.net/blogs/exchange/archive/2010/05/29/Using-Scriping-Agent-to-cause-automatic-events-to-occur-in-Exchange-2010-_2D00_-life-just-got-simpler_2100_.aspx">this </a>post.  Using the Scripting Agent you can have Exchange ActiveSync disabled whenever a mailbox is created for a new or existing user.  This removes the need to do it directly against Active Directory through some workflow mechanism or scheduling a task to run that does it with the <span class="flobeecode" id="codekeyword">Set-CASMailbox</span> cmdlet.</p>
<p>There is almost no documentation on the use of the provisioning handler for Exchange 2010, leaving me to do a lot of trial and error to get it working for new mailboxes for both new and existing users.  It doesn&#8217;t look like the provisioning handler has access to any of the information returned by the success of the <span class="flobeecode" id="codekeyword">New-Mailbox</span> and <span class="flobeecode" id="codekeyword">Enable-Mailbox</span> cmdlets.  This means it only has access to the information submitted by the user in a cmdlet.  Because you supply different information when creating a mailbox for a new user compared to an existing one, the code has to be different for each.</p>
<p>Copy the code below into the ScriptingAgentConfig.xml file and, as Pat Richard&#8217;s post details, put it in the CmdletExtensionAgents directory and enable the Scripting Agent.</p>
<pre class="brush:ps;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;
&lt;Configuration version=&quot;1.0&quot;&gt;
	&lt;Feature Name=&quot;MailboxProvisioning&quot; Cmdlets=&quot;enable-mailbox&quot;&gt;
		&lt;ApiCall Name=&quot;OnComplete&quot;&gt;
			if($succeeded)
				{
				$user = (Get-User $provisioningHandler.UserSpecifiedParameters[&quot;Identity&quot;]).distinguishedName
				Set-CASMailbox $user -ActiveSyncEnabled $false
				}
		&lt;/ApiCall&gt;
	&lt;/Feature&gt;
	&lt;Feature Name=&quot;MailboxProvisioning&quot; Cmdlets=&quot;new-mailbox&quot;&gt;
		&lt;ApiCall Name=&quot;OnComplete&quot;&gt;
			if($succeeded)
				{
				$user = (Get-User $provisioningHandler.UserSpecifiedParameters[&quot;Name&quot;]).distinguishedName
				Set-CASMailbox $user -ActiveSyncEnabled $false
				}
		&lt;/ApiCall&gt;
	&lt;/Feature&gt;
&lt;/Configuration&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.flobee.net/automatically-disable-activesync-for-new-mailboxes-in-exchange-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Exchange 2010 prerequisite installation script updated</title>
		<link>http://www.flobee.net/exchange-2010-prerequisite-installation-script-updated/</link>
		<comments>http://www.flobee.net/exchange-2010-prerequisite-installation-script-updated/#comments</comments>
		<pubDate>Mon, 28 Jun 2010 16:49:38 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[Exchange 2010]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://www.flobee.net/?p=498</guid>
		<description><![CDATA[Edit on August 24, 2010: Script updated to version 1.5.  See notes here.
I have made a couple of minor updates to the prerequisite installation script.  One is changing the way the source directory is determined.  Instead of hardcoding the directory, the directory that the script is running from will be used.  [...]]]></description>
			<content:encoded><![CDATA[<p><font color="green">Edit on August 24, 2010: Script updated to version 1.5.  See notes <a href="http://www.flobee.net/exchange-2010-prerequisite-installation-script-updated-2/">here</a>.</font></p>
<p>I have made a couple of minor updates to the prerequisite installation script.  One is changing the way the source directory is determined.  Instead of hardcoding the directory, the directory that the script is running from will be used.  This allows you to simply put all files in the same directory as the script and run it from anywhere (except for UNC).</p>
<p>Another change is a correction when checking for installation binaries.  I failed to account for the backslash between the directory and the filename so, even when the file exists, the script wouldn&#8217;t see it.</p>
<p>The last change is moving the NETTCPPortSharing service setting after the Windows components installation completes so that the setting is immediately configured.  This allows you to begin the Exchange installation without rebooting.</p>
<p>The download and inline code from the <a href="http://www.flobee.net/script-to-install-all-exchange-2010-prerequisites/">original post</a> have been updated.<br />
Note: There is a file embedded within this post, please visit this post to download the file.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.flobee.net/exchange-2010-prerequisite-installation-script-updated/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Script to install all Exchange 2010 prerequisites</title>
		<link>http://www.flobee.net/script-to-install-all-exchange-2010-prerequisites/</link>
		<comments>http://www.flobee.net/script-to-install-all-exchange-2010-prerequisites/#comments</comments>
		<pubDate>Thu, 10 Jun 2010 20:55:43 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[Exchange 2010]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[inline code]]></category>

		<guid isPermaLink="false">http://www.flobee.net/?p=491</guid>
		<description><![CDATA[Edit on August 24, 2010: Script updated to version 1.5.  See notes here.
There are already several sites which have scripts to install Exchange 2010 prerequisites, but they all seem to fall short in one aspect or another.  Some make you choose the right script if you are on 2008 or 2008 R2.  [...]]]></description>
			<content:encoded><![CDATA[<p><font color="green">Edit on August 24, 2010: Script updated to version 1.5.  See notes <a href="http://www.flobee.net/exchange-2010-prerequisite-installation-script-updated-2/">here</a>.</font></p>
<p>There are already several sites which have scripts to install Exchange 2010 prerequisites, but they all seem to fall short in one aspect or another.  Some make you choose the right script if you are on 2008 or 2008 R2.  Others download some files but not others.  None make sure that WinRM is installed, which is needed for PowerShell v2.  So I started with a great script and made it better.  My starting point is <a href="http://www.bhargavs.com/index.php/2009/11/18/script-to-install-exchange-2010-pre-requisites-for-windows-server-2008-r2/">Bhargav Shukla&#8217;s script</a>, which in turn started elsewhere.</p>
<p>My script checks whether the server is running Windows Server 2008 SP2 or Windows Server 2008 R2.  (If you aren&#8217;t running SP2, it will tell you.)  Because the command to add the Windows components is different between them (ServerManagerCmd.exe in DOS and Add-WindowsFeature in PowerShell), the appropriate command will be run.</p>
<p>Instead of just downloading the 2007 Office Filter Pack, I added the option to download each file (including WinRM) if it isn&#8217;t installed and not in the installation source directory.  I also chose to install the 2010 Office Filter Pack, which includes support for 2007.</p>
<p>If Windows Remote Management isn&#8217;t installed, it will install it and reboot the server.  You don&#8217;t have to uninstall PowerShell v1 to do this, so you can run the script and install WinRM, then run the script again after the reboot to continue (which is then implicitly using PowerShell v2).</p>
<p>I also added functions to enable remote PowerShell and enable the Windows Firewall service.  The latter is required for Exchange setup to be successful so it can create the firewall exceptions.  You can always disable the service after setup is complete.</p>
<p>I added the option to install the HT and CAS roles together, should that apply to you.</p>
<p>If you want to download the required files ahead of time and put them in the same directory as the script, they are listed below (direct download links).  Note that I renamed the filter pack installation file to 2010FilterPack64bit.exe in order to distinguish it from the Office 2007 Filter Pack installation file.  If you have the 2007 Filter pack installed, the 2010 install will replace it upon installation.  If you manually download the filter pack, though, remember to rename it.</p>
<ul>
<li><a href="http://download.microsoft.com/download/2/8/6/28686477-3242-4E96-9009-30B16BED89AF/Windows6.0-KB968930-x64.msu">Windows Remote Management Framework</a> (14MB)</li>
<li><a href="http://download.microsoft.com/download/2/0/e/20e90413-712f-438c-988e-fdaa79a8ac3d/dotnetfx35.exe">.NET 3.5 SP1 Redistributable installation</a> (235MB)</li>
<li><a href="http://download.microsoft.com/download/B/4/2/B42197BD-AEE1-4FE6-8CB3-29D60D0C3727/Windows6.0-KB958483-x64.msu">.NET 3.5 SP1 hotfix</a> (1.4MB)</li>
<li><a href="http://download.microsoft.com/download/0/A/2/0A28BBFA-CBFA-4C03-A739-30CCA5E21659/FilterPack64bit.exe">Office 2010/2007 Filter Pack</a> (4MB)</li>
<li>The Exchange-<i>Role</i>.xml files from the installation media&#8217;s Scripts directory</li>
</ul>
<p>You can copy the script inline below, or download it via the link at the bottom of the post.</p>
<pre class="brush: ps">
#Installs prerequisites necessary to install Exchange 2010 on
#Windows 2008 SP2 or Windows 2008 R2.
#Version 1.3
#Last modified: June 28, 2010

#Set installation source to same directory as script execution
$sourcePath = Split-Path -Parent $MyInvocation.MyCommand.Path

Write-Host 'Using ' -NoNewline
Write-Host $sourcePath -ForegroundColor DarkGreen -NoNewline
Write-Host ' as the installation source.'

# Detect correct OS here and exit if no match
if ((Get-WMIObject win32_OperatingSystem).Version -eq '6.1.7600')
	{$os = 'R2'}
elseif ((Get-WMIObject win32_OperatingSystem).Version -eq '6.0.6002')
	{$os = 'R1'}
else
	{
	Write-Host 'This script requires Windows Server 2008 with SP2, or R2, which this is not.' -ForegroundColor Red -BackgroundColor Black
	break
	}

#Installation files and properties (filename, shortname, displayname, download URL, size)
$fileWinRM = ('Windows6.0-KB968930-x64.msu','WinRM','Windows Remote Management Framework','http://download.microsoft.com/download/2/8/6/28686477-3242-4E96-9009-30B16BED89AF/Windows6.0-KB968930-x64.msu','14MB')
$fileNET35 = ('dotnetfx35.exe','.NET 3.5','.NET 3.5 SP1','http://download.microsoft.com/download/2/0/E/20E90413-712F-438C-988E-FDAA79A8AC3D/dotnetfx35.exe','235MB')
$fileNET35HF = ('NDP35SP1-KB958484-x64.exe','.NET 3.5 hotfix','.NET 3.5 hotfix','http://download.microsoft.com/download/B/4/2/B42197BD-AEE1-4FE6-8CB3-29D60D0C3727/Windows6.0-KB958483-x64.msu','1.4MB')
$fileOFP = ('2010FilterPack64bit.exe','Office 2010 Filter Pack','Office 2010/2007 Filter Pack','http://download.microsoft.com/download/0/A/2/0A28BBFA-CBFA-4C03-A739-30CCA5E21659/FilterPack64bit.exe','4MB')

Function InstallApp($app)
	{
	switch ($app)
		{
		'WinRM'
			{
			$appArray = $fileWinRM
			$kb = 'KB968930'
			}
		'NET35'
			{
			$appArray = $fileNET35
			$checkExpression = "test-path 'HKLM:Software\Microsoft\NET Framework Setup\NDP\v3.5'"
			}
		'NET35HF'
			{
			$appArray = $fileNET35HF
			$checkExpression = "test-path 'HKLM:SOFTWARE\Wow6432Node\Microsoft\Updates\Microsoft .NET Framework 3.5 SP1\SP1\KB958484'"
			}
		'OFP'
			{
			$appArray = $fileOFP
			$checkExpression = "test-path 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\{95140000-2000-0409-1000-0000000FF1CE}'"
			}
		}
	trap
		{
		Write-Host ''
		Write-Host "There was a problem downloading or installing $($appArray[1])." -ForegroundColor Red
		Write-Host ''
		break
		}
	#Check for existing installation
	Write-Host "Verifying $($appArray[2]) is installed..." -NoNewline
	if ($app -eq 'WinRM')
		{
		$hfInst = Get-WMIObject Win32_QuickFixEngineering | where {$_.HotFixID -eq $kb}
		if ($hfInst)
			{
			$bInstalled = $true
			}
		else
			{
			$bInstalled = $false
			}
		}
	else
		{
		if (Invoke-Expression $checkExpression)
			{
			$bInstalled = $true
			}
		else
			{
			$bInstalled = $false
			}
		}
	if ($bInstalled)
		{
		Write-Host "$($appArray[2]) is installed." -ForegroundColor Green
		return
		}
	Write-Host "$($appArray[2]) is not installed." -ForegroundColor Red
	Write-Host "Installing $($appArray[2])..." -NoNewline

	#Install app:  Check for existing installation file.
	$fullPath = $sourcePath+"\$($appArray[0])"
	if (!(Test-Path $fullPath))
		{
		Write-Host ''
		Write-Host "$($appArray[0]) not found in source path." -ForegroundColor Yellow
		$dl = Read-Host "Do you want to download it now? ($($appArray[4]))(Y/N)"
		if ($dl -ne 'y')
			{
			Write-Host "You have chosen to not download the $($appArray[1]) installation file."
			Write-Host "Put $($appArray[0]) in the source directory and run the script again."
			break
			}
		else
			{
			Write-Host "Downloading $($appArray[1])..." -NoNewline
			$dlClient = New-Object System.Net.WebClient
			$dlClient.DownloadFile($appArray[3],$fullPath)
			if (!(Test-Path $fullPath))
				{
				Write-Host ''
				Write-Host "There was a problem downloading $($appArray[1])." -ForegroundColor Red
				Write-Host ''
				}
			else
				{
				Write-Host 'done.' -ForegroundColor Green
				}
			}
		}

	#Install app: Run installation.
	if ($app -eq 'WinRM')
		{
		$expression = "wusa $fullPath /quiet"
		Invoke-Expression $expression
		Write-Host 'External update process started...Be patient, it takes time.' -ForegroundColor Yellow
		Write-Host ''
		Write-Host 'When the WinRM installation is complete, the system will automatically reboot.'
		Write-Host 'Then you can rerun the script to continue.  This script will now end.'
		break
		}
	else
		{
		if ($app -eq 'NET35HF')
			{$arguments = '/passive /norestart'}
		else
			{$arguments = '/quiet /norestart'}
		$process = [System.Diagnostics.Process]::Start($fullPath,$arguments)
		$process.WaitForExit()
		Write-Host "$($appArray[1]) installation complete." -ForegroundColor Green
		}
	}	

Function InstallNET35()
	{
	InstallApp('NET35')
	InstallApp('NET35HF')
	}

Function SetTCPSharing()
	{
	trap
		{
		Write-Host ''
		Write-Host 'There was problem setting the NET TCP Port Sharing service to Automatic startup.' -ForegroundColor Red
		Write-Host 'The service must be set to Automatic for Exchange setup to be successful.' -ForegroundColor Red
		Write-Host ''
		return
		}
	#Set NETTCPPortSharing to Automatic
	Write-Host 'Configuring the NET TCP Port Sharing service...' -NoNewline
	Set-Service NetTcpPortSharing -StartupType Automatic
	Write-Host 'done.' -ForegroundColor Green
	}

Function EnableRemoting()
	{
	trap
		{
		Write-Host ''
		Write-Host 'There was problem configuring the system for remote PowerShell.' -ForegroundColor Red
		Write-Host ''
		return
		}
	#Enable Remote PowerShell for Exchange administration from workstations
	Write-Host 'Enabling system for remote PowerShell connections...'
	Enable-PSRemoting -force
	Write-Host 'Remote PowerShell configuration is done.' -ForegroundColor Green
	}

Function EnableFirewall()
	{
	trap
		{
		Write-Host ''
		Write-Host 'There was problem starting the Windows Firewall service.' -ForegroundColor Red
		Write-Host 'The firewall service must be running during Exchange setup.  It can be stopped after it completes.' -ForegroundColor Red
		Write-Host ''
		return
		}
	#Ensure Windows Firewall is running or Exchange install will fail
	Write-Host 'Starting the Windows Firewall service...' -NoNewline
	Set-Service 'MpsSvc' -StartupType Automatic -Status Running
	Write-Host 'done.' -ForegroundColor Green
	}

if ($os -eq 'R1')
	{
	$ht = '. ServerManagerCmd.exe -ip '+$sourcePath+'\Exchange-Hub.xml'
	$cas = '. ServerManagerCmd.exe -ip '+$sourcePath+'\Exchange-CAS.xml'
	$mbx = '. ServerManagerCmd.exe -ip '+$sourcePath+'\Exchange-MBX.xml'
	$um = '. ServerManagerCmd.exe -ip '+$sourcePath+'\Exchange-UM.xml'
	$edge = '. ServerManagerCmd.exe -ip '+$sourcePath+'\Exchange-Edge.xml'
	$typical = '. ServerManagerCmd.exe -ip '+$sourcePath+'\Exchange-Typical.xml'
	}
elseif ($os -eq 'R2')
	{
	$ht = 'Add-WindowsFeature NET-Framework,RSAT-ADDS,Web-Server,Web-Basic-Auth,Web-Windows-Auth,Web-Metabase,Web-Net-Ext,Web-Lgcy-Mgmt-Console,WAS-Process-Model,RSAT-Web-Server -restart'
	$cas = 'Add-WindowsFeature NET-Framework,RSAT-ADDS,Web-Server,Web-Basic-Auth,Web-Windows-Auth,Web-Metabase,Web-Net-Ext,Web-Lgcy-Mgmt-Console,WAS-Process-Model,RSAT-Web-Server,Web-ISAPI-Ext,Web-Digest-Auth,Web-Dyn-Compression,NET-HTTP-Activation,RPC-Over-HTTP-Proxy -restart'
	$mbx = 'Add-WindowsFeature NET-Framework,RSAT-ADDS,Web-Server,Web-Basic-Auth,Web-Windows-Auth,Web-Metabase,Web-Net-Ext,Web-Lgcy-Mgmt-Console,WAS-Process-Model,RSAT-Web-Server -restart'
	$um = 'Add-WindowsFeature NET-Framework,RSAT-ADDS,Web-Server,Web-Basic-Auth,Web-Windows-Auth,Web-Metabase,Web-Net-Ext,Web-Lgcy-Mgmt-Console,WAS-Process-Model,RSAT-Web-Server,Desktop-Experience -restart'
	$edge = 'Add-WindowsFeature NET-Framework,RSAT-ADDS,ADLDS -restart'
	$typical = 'Add-WindowsFeature NET-Framework,RSAT-ADDS,Web-Server,Web-Basic-Auth,Web-Windows-Auth,Web-Metabase,Web-Net-Ext,Web-Lgcy-Mgmt-Console,WAS-Process-Model,RSAT-Web-Server,Web-ISAPI-Ext,Web-Digest-Auth,Web-Dyn-Compression,NET-HTTP-Activation,RPC-Over-HTTP-Proxy -restart'
	Import-Module ServerManager
	}
$opt = 'None'

InstallApp('WinRM')

clear
if ($opt -ne 'None') {write-host 'Last command: '$opt -foregroundcolor Yellow}
write-host
write-host 'Exchange Server 2010 Prerequisites Installation'
write-host 'Please select which role you are going to install:'
write-host
write-host '1)  Hub Transport'
write-host '2)  Client Access Server'
write-host '3)  Mailbox'
write-host '4)  Unified Messaging'
write-host '5)  Edge Transport'
write-host '6)  Typical (CAS\HT\Mailbox)'
write-host '7)  Client Access and Hub Transport'
write-host
write-host '9)  Configure NetTCP Port Sharing service'
write-host '    Required for the Client Access Server role' -foregroundcolor yellow
write-host '    Automatically set for options 2,6, and 7' -foregroundcolor yellow
write-host '10) Install 2010 Office System Converter: Microsoft Filter Pack'
write-host '    Required if installing Hub Transport or Mailbox Server roles' -foregroundcolor yellow
write-host '    Automatically set for options 1,3,6, and 7' -foregroundcolor yellow
Write-Host '11) Enable PowerShell Remoting'
Write-Host '    Automatically set for options 1,2,3,4,6, and 7' -ForegroundColor Yellow
write-host
write-host '13) Restart the Server'
write-host '14) End'
write-host
Write-Host 'Note: Using ' -NoNewline
Write-Host $sourcePath -ForegroundColor DarkGreen -NoNewline
Write-Host ' as the installation source.'
$opt = Read-Host 'Select an option.. [1-14]? '

switch ($opt)
	{
	1{
		InstallNET35; InstallApp('OFP'); EnableFirewall; EnableRemoting
		Write-Host 'Beginning Windows components installation...'
		Invoke-Expression $ht
	  	}
	2{
		InstallNET35; EnableFirewall; EnableRemoting
		Write-Host 'Beginning Windows components installation...'
		Invoke-Expression $cas
        SetTCPSharing
		}
	3{
		InstallNET35; InstallApp('OFP'); EnableFirewall; EnableRemoting
		Write-Host 'Beginning Windows components installation...'
		Invoke-Expression $mbx
		}
	4{
		InstallNET35; EnableRemoting; EnableFirewall
		Write-Host 'Beginning Windows components installation...'
		Invoke-Expression $um
		}
	5{
		InstallNET35; EnableFirewall
		Write-Host 'Beginning Windows components installation...'
		Invoke-Expression $edge
		}
	6{
		InstallNET35; InstallApp('OFP'); EnableFirewall; EnableRemoting
		Write-Host 'Beginning Windows components installation...'
		Invoke-Expression $typical
        SetTCPSharing
		}
	7{
		InstallNET35; InstallApp('OFP'); EnableFirewall; EnableRemoting
		Write-Host 'Beginning Windows components installation...'
		Invoke-Expression $cas
        SetTCPSharing
		}
	9 { SetTCPSharing }
	10 { InstallApp('OFP') }
	11 { EnableRemoting }
	13 { Restart-Computer }
	14 {write-host 'Exiting...'}
	default {write-host "You haven't selected any of the available options."}
	}
</pre>
Note: There is a file embedded within this post, please visit this post to download the file.
]]></content:encoded>
			<wfw:commentRss>http://www.flobee.net/script-to-install-all-exchange-2010-prerequisites/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Determine the proxy server when automatic detection is used</title>
		<link>http://www.flobee.net/determine-the-proxy-server-when-automatic-detection-is-used/</link>
		<comments>http://www.flobee.net/determine-the-proxy-server-when-automatic-detection-is-used/#comments</comments>
		<pubDate>Thu, 25 Mar 2010 16:09:58 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[inline code]]></category>

		<guid isPermaLink="false">http://www.flobee.net/?p=476</guid>
		<description><![CDATA[If a browser is configured to detect proxy server settings automatically, the proxy server address is never displayed anywhere in the browser.  You may have an application, however, that requires you to explicitly define the proxy server to use.  To determine the server to use, you can use PowerShell.  (You can&#8217;t do [...]]]></description>
			<content:encoded><![CDATA[<p>If a browser is configured to detect proxy server settings automatically, the proxy server address is never displayed anywhere in the browser.  You may have an application, however, that requires you to explicitly define the proxy server to use.  To determine the server to use, you can use PowerShell.  (You can&#8217;t do it as a one-liner because the <span class="flobeecode" id="codeplain">System.Net.WebClient</span> class doesn&#8217;t have any static methods, which means you have to load the class before you can call any of the methods.)</p>
<pre class="brush:ps;collapse:false;light:true;auto-links:false">
$webclient = new-object System.Net.WebClient
$webclient.Proxy.GetProxy("http://www.cnn.com").Authority
</pre>
<p>The URL to use in the query can be anything as long as it is one that will evaluate to using a proxy server, so don&#8217;t use an internal address that will evaluate to connecting directly.  The query will return the DNS name of the proxy server and the port to use, e.g., proxy.company.com:8080.  If you want these values separately, you can use the Host and Port properties.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.flobee.net/determine-the-proxy-server-when-automatic-detection-is-used/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Update to OCS archiving script</title>
		<link>http://www.flobee.net/update-to-ocs-archiving-script/</link>
		<comments>http://www.flobee.net/update-to-ocs-archiving-script/#comments</comments>
		<pubDate>Mon, 01 Mar 2010 18:29:51 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[OCS 2007]]></category>
		<category><![CDATA[OCS 2007 R2]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://www.flobee.net/?p=471</guid>
		<description><![CDATA[There are a couple of changes that have been made to improve the script.
First, after running a report for a user with thousands of messages and not having any idea of the progress while it was running, I added progress windows during the two phases (content conversion and HTML report creation).  The progress window [...]]]></description>
			<content:encoded><![CDATA[<p>There are a couple of changes that have been made to improve the script.</p>
<p>First, after running a report for a user with thousands of messages and not having any idea of the progress while it was running, I added progress windows during the two phases (content conversion and HTML report creation).  The progress window will tell you how many messages will be processed and how far along it is in that process.</p>
<p>Second, I discovered that hyperlinks in messages were not showing up in the report.  Looking at the HTML (or XML) source, I could see the link was there, but the way it was formatted in the XML file (using element enclosures) meant the conversion to HTML was confusing the parser.  Now I remove those characters prior to the link being written to the XML file.</p>
<p>I also optimized the message body conversion loop to remove redundant or obsolete code that was in the original script.  There are also some minor cosmetic changes here and there.</p>
<p>Lastly, I realized last week that the script only reports on peer-to-peer (P2P) conversations, not multiparty.  I spent some time trying to get multiparty conversations out of the database, but it is proving much more difficult than I anticipated.  The format of multiparty IMs in the archiving database is very different than P2P conversations.  I am still working on it, but I am not sure I will be able to make it work.  In the meantime, I added a note in the report that states it is only for P2P conversations.</p>
<p>The original zip file with the script has been updated, but you can download it here:<br />
Note: There is a file embedded within this post, please visit this post to download the file.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.flobee.net/update-to-ocs-archiving-script/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Script to compare deployed BlackBerry handheld firmware with a local repository</title>
		<link>http://www.flobee.net/script-to-compare-deployed-blackberry-handheld-firmware-with-a-local-repository/</link>
		<comments>http://www.flobee.net/script-to-compare-deployed-blackberry-handheld-firmware-with-a-local-repository/#comments</comments>
		<pubDate>Tue, 09 Feb 2010 19:08:07 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[BlackBerry]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[inline code]]></category>

		<guid isPermaLink="false">http://www.flobee.net/?p=463</guid>
		<description><![CDATA[If you use, say, BlackBerry Web Desktop Manager to facilitate firmware upgrades for users, then you have a bunch of them installed somewhere.  (I have 49 versions among 15 carriers.)  I keep a list of the ones I have installed, but I wanted to be able to compare that to what is actually [...]]]></description>
			<content:encoded><![CDATA[<p>If you use, say, BlackBerry Web Desktop Manager to facilitate firmware upgrades for users, then you have a bunch of them installed somewhere.  (I have 49 versions among 15 carriers.)  I keep a list of the ones I have installed, but I wanted to be able to compare that to what is actually in use among all the users in the organization.  This way I can know which installs are obsolete, when new models are in use, and when newer versions are in use by users.</p>
<p>To use this script, in BlackBerry Manager (I am using 4.1.6) highlight all of your users and right-click on them, then select Export Asset Summary Data.  The script will look for BESHandhelds.txt, but you can edit it to be whatever you want.  The file that I use to track installed versions is just a csv with the following headers: Carrier, Model, Model Name, Version, Installed.  Model Name is not used in the script, but mirrors the fields I use in an internal KB article that users can reference.  Here is a sample table of entries:</p>
<table align="center" border="1">
<tbody>
<tr>
<td>Carrier</td>
<td>Model</td>
<td>Model Name</td>
<td>Version</td>
<td>Installed</td>
</tr>
<tr>
<td>AT&amp;T</td>
<td>8320</td>
<td>Curve</td>
<td>4.5.0.182</td>
<td></td>
</tr>
<tr>
<td>AT&amp;T</td>
<td>8520</td>
<td>Curve</td>
<td>4.6.1.314</td>
<td>No</td>
</tr>
<tr>
<td>KPN</td>
<td>8820</td>
<td></td>
<td>4.5.0.55</td>
<td></td>
</tr>
</tbody>
</table>
<p>I added the Installed field as a way to track models that don&#8217;t actually have a local installation either because there is only one release from the carrier or all handhelds are already on that version so there isn&#8217;t a reason to have it installed.  The script will look for a file called BBFirmware.csv but, again, you can change it to whatever you want.</p>
<p>The <span class="flobeecode" id="codekeyword">switch</span> statement starting in line 17 is to map the carrier name as recorded in BES to how I record it in my file.  The output of the script will let you know carriers that are not defined in the statement, but you will want to add or remove carriers as necessary first.</p>
<p>The output will also let you know if a model is in use that is not found in your installation file, if a there is a newer version for a particular model that is in use, and if all users are using the latest version you have installed.  What this script does <i>not</i> do is determine if you have the latest version that has been released by the carrier (since that would be much harder to do).  Lastly, it will let you know of installations you have for models that are not in use anymore so that you can uninstall them.</p>
<p>I am a perfectionist, so I can already see ways to improve the script, but I would never be done if I didn&#8217;t stop somewhere.  You can download the ps1 file below.<br />
Note: There is a file embedded within this post, please visit this post to download the file.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.flobee.net/script-to-compare-deployed-blackberry-handheld-firmware-with-a-local-repository/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OCS Archiving Reporter: Group by conversation, filter dates</title>
		<link>http://www.flobee.net/ocs-archiving-reporter-group-by-conversation-filter-dates/</link>
		<comments>http://www.flobee.net/ocs-archiving-reporter-group-by-conversation-filter-dates/#comments</comments>
		<pubDate>Fri, 04 Dec 2009 00:46:21 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[OCS 2007]]></category>
		<category><![CDATA[OCS 2007 R2]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[inline code]]></category>

		<guid isPermaLink="false">http://www.flobee.net/?p=433</guid>
		<description><![CDATA[Edit:  The inline code is not the latest version of the script.  To get the latest version, download the full script on the Downloads page (or via the link at the end of the post).
The foundation for my script is from the OCS team at Microsoft, who created the original version.
The script from [...]]]></description>
			<content:encoded><![CDATA[<p><font color="red">Edit:</font>  The inline code is not the latest version of the script.  To get the latest version, download the full script on the <a href="http://www.flobee.net/downloads">Downloads</a> page (or via the link at the end of the post).</p>
<p>The foundation for my script is from the OCS team at Microsoft, who created the <a href="http://communicationsserverteam.com/archive/2009/09/28/584.aspx">original version</a>.</p>
<p>The script from Microsoft grabs all the messages and outputs them all in one big table.  I wanted it to be displayed more logically, grouping an entire conversation (session) together so it is easier to follow the context of the messages.  This proved to be more daunting than I had anticipated.</p>
<p>All messages that occur in the same session have the same value for the SessionIdTime.  With that I can group those messages together.  But I needed a way to know when a new conversation started and ended. To get that I used the RANK function in SQL so that any rank of 1 indicates a new conversation.  The resulting SQL query for a single user is the following (the ticks at the end of the lines are for PowerShell):</p>
<pre class="brush:sql;gutter:false">
SELECT RANK() OVER(PARTITION BY SessionIdTime ORDER BY SessionIdTime, MessageIdTime) AS 'Rank', `
	SessionIdTime, MessageIdTime, Body, ContentTypeId, [from], [to] `
FROM `
(SELECT SessionIdTime, MessageIdTime, Body, ContentTypeId, u1.UserUri AS [from], u2.UserUri AS [to] FROM Messages, `
	Users u1, Users u2 WHERE Messages.FromId = u1.UserId AND Messages.ToId = u2.UserId AND u1.UserUri = '$User1' `
	AND LcsLog.dbo.Messages.Toast IS NULL `
UNION ALL `
SELECT SessionIdTime, MessageIdTime, Body, ContentTypeId, u2.UserUri AS [from], u1.UserUri AS [to] FROM Messages, `
	Users u2, Users u1 WHERE Messages.FromId = u2.UserId AND Messages.ToId = u1.UserId AND u1.UserUri = '$User1' `
	AND LcsLog.dbo.Messages.Toast IS NULL `
)AS dConversation
</pre>
<p>Now that I had the data, I needed to be able to use the XSLT to conditionally close a table the next time a rank of 1 is in the loop.  I had the hardest time trying to make the xsl:if and xsl:choose statements work.  Trying to include a <span class="flobeecode" id="codekeyword">&lt;/table&gt;</span> tag without the loop seeing the opening tag only caused errors.  If I used HTML notation, <span class="flobeecode" id="codekeyword">&amp;lt;/table&amp;gt;</span>, those characters were rendered as their literal ASCII representations rather than being parsed as HTML tags.</p>
<p>After trying for many, many hours, I decided to give up relying on the XML parser to convert the file to HTML and just do that parsing in the PowerShell script.  This has the benefit of not requiring external files to run the script (the XSLT and msxsl.exe).  The code below takes the XML output from the first part of the script and loops through each node (message).  If the rank is 1, it closes the previous table, opens a new one, and writes the message to a row.  If the rank is not 1, it means that a conversation has already been started and the message can simply being written in a new row.</p>
<pre class="brush:ps">
#Convert XML to HTML
$sourceXML = [xml](Get-Content $LocalPath)
Remove-Item -path IM.html -ea SilentlyContinue
pwd | % {[string]$LocalPath = $_.path}
$LocalPath = $LocalPath + "\IM.html"
Add-Content -path $LocalPath -Value '&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"'
Add-Content -Path $LocalPath -Value '  "http://www.w3.org/TR/html4/loose.dtd"&gt;'
Add-Content -Path $LocalPath -Value "&lt;html&gt;"
Add-Content -Path $LocalPath -Value "&lt;head&gt;"
Add-Content -Path $LocalPath -Value "&lt;title&gt;IM Conversation Archive&lt;/title&gt;"
Add-Content -Path $LocalPath -Value "&lt;/head&gt;"
Add-Content -Path $LocalPath -Value "&lt;body&gt;"

Add-Content -Path $LocalPath -Value '&lt;font size="2" face="Verdana"&gt;'
Add-Content -Path $LocalPath -Value "&lt;h2 align=`"center`"&gt;$($sourceXML.IMConversation.Title)&lt;/h2&gt;"
Add-Content -Path $LocalPath -Value "&lt;h3 align=`"center`"&gt;$($sourceXML.IMConversation.Subtitle)&lt;/h2&gt;"
Add-Content -Path $LocalPath -Value "&lt;/font&gt;"
Add-Content -Path $LocalPath -Value '&lt;table border="0" cellpadding="1" width="100%" style="FONT-SIZE:8pt;FONT-FAMILY:verdana"&gt;'
foreach($IM in $sourceXML.IMConversation.IM)
	{
	if ($IM.Rank -eq "1")
		{
		Add-Content -Path $LocalPath -Value "&lt;/tbody&gt;&lt;/table&gt;&lt;br&gt;"
		Add-Content -Path $LocalPath -Value '&lt;table border="1" cellpadding="1" width="100%" style="FONT-SIZE:8pt;FONT-FAMILY:verdana">'
		Add-Content -Path $LocalPath -Value '&lt;thead>&lt;tr bgcolor="#C0C0C0" align="center"&gt;'
		Add-Content -Path $LocalPath -Value	'&lt;th&gt;&lt;font color="#0000FF"&gt;Session Time (UTC):&lt;/font&gt;&lt;/th&gt;'
		Add-Content -Path $LocalPath -Value	'&lt;th&gt;&lt;font color="#0000FF"&gt;Message Time (UTC):&lt;/font&gt;&lt;/th&gt;'
		Add-Content -Path $LocalPath -Value	'&lt;th&gt;&lt;font color="#0000FF"&gt;From:&lt;/font&gt;&lt;/th&gt;'
		Add-Content -Path $LocalPath -Value	'&lt;th&gt;&lt;font color="#0000FF"&gt;To:&lt;/font&gt;&lt;/th&gt;'
		Add-Content -Path $LocalPath -Value '&lt;th width="40%"&gt;&lt;font color="#0000FF"&gt;Message:&lt;/font&gt;&lt;/th&gt;'
		Add-Content -Path $LocalPath -Value	"&lt;/tr&gt;&lt;/thead&gt;"
		Add-Content -Path $LocalPath -Value	"&lt;tbody&gt;&lt;tr&gt;"
		Add-Content -Path $LocalPath -Value	"&lt;td rowspan=`"100`" valign=`"top`"&gt;$($IM.SessionTime)&lt;/td&gt;"
		Add-Content -Path $LocalPath -Value	"&lt;td&gt;$($IM.DateTime)&lt;/td&gt;"
		Add-Content -Path $LocalPath -Value	"&lt;td&gt;$($IM.From)&lt;/td&gt;"
		Add-Content -Path $LocalPath -Value	"&lt;td&gt;$($IM.To)&lt;/td&gt;"
		Add-Content -Path $LocalPath -Value	"&lt;td&gt;$($IM.Body.get_FirstChild().get_Data())&lt;/td&gt;"
		Add-Content -Path $LocalPath -Value	"&lt;/tr&gt;"
		}
	else
		{
		Add-Content -Path $LocalPath -Value	"&lt;tr&gt;"
		Add-Content -Path $LocalPath -Value	"&lt;td&gt;$($IM.DateTime)&lt;/td&gt;"
		Add-Content -Path $LocalPath -Value	"&lt;td&gt;$($IM.From)&lt;/td&gt;"
		Add-Content -Path $LocalPath -Value	"&lt;td&gt;$($IM.To)&lt;/td&gt;"
		Add-Content -Path $LocalPath -Value	"&lt;td&gt;$($IM.Body.get_FirstChild().get_Data())&lt;/td&gt;"
		Add-Content -Path $LocalPath -Value	"&lt;/tr&gt;"
		}
	}

Add-Content -Path $LocalPath -Value "&lt;/table>"
Add-Content -Path $LocalPath -Value "&lt;/body>"
Add-Content -Path $LocalPath -Value "&lt;/html>"
</pre>
<p>Lastly, I wanted to be able to filter on a date range within the archiving database.  So I added two arguments to the script after the users: <span class="flobeecode" id="codekeyword">-start</span> and <span class="flobeecode" id="codekeyword">-end</span>, both which are independently optional.  If you don&#8217;t specify a second user or you only specify an end date with one or two users, you need to use the parameter names in the command.  Otherwise, they are positional.  The date format to use is <span class="flobeecode" id="codestring">&quot;YYYY-MM-DD&quot;</span>.  To account for the presence of the date filter, this code is added to the script:</p>
<pre class="brush:ps">
If ($start -ne '')
	{
	#Start date has been specified
	$startdate = $start
	$start = "and Messages.MessageIdTime &gt;= '$start' "
	}
Else
	{
	$startdate = "Oldest record in the database"
	}

If ($end -ne '')
	{
	#End date has been specified
	$enddate = $end
	$end = "and Messages.MessageIdTime &lt;= '$end' "
	}
Else
	{
	$enddate = "Newest record in the database"
	}
</pre>
<p>The code is able to correctly parse the presence of a start date, end date, or both.  Now the following can be added to the end of the code block in the SQL query that makes up the derived table (the part in the nested parentheses):  <span class="flobeecode" id="codekeyword">+</span> <span class="flobeecode" id="codevariable">$start</span> <span class="flobeecode" id="codekeyword">+</span> <span class="flobeecode" id="codevariable">$end</span> <span class="flobeecode" id="codekeyword">+</span>.</p>
<p>Finally, the output is a pretty page with the subtitle that indicates the date range used, the table headers are formatted to visually separate each conversation, and each table is an indicated of a single conversation, regardless of the number of messages shown.</p>
<p>I don&#8217;t expect you to copy and paste all the code above into the script and have it magically work (especially since I made other minor changes to account for the subtitle, additional arguments, etc.), so you can download the entire script below or on the <a href="http://www.flobee.net/downloads">Downloads</a> page.Note: There is a file embedded within this post, please visit this post to download the file.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.flobee.net/ocs-archiving-reporter-group-by-conversation-filter-dates/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Exclude toast messages from OCS archiving report</title>
		<link>http://www.flobee.net/exclude-toast-messages-from-ocs-archiving-report/</link>
		<comments>http://www.flobee.net/exclude-toast-messages-from-ocs-archiving-report/#comments</comments>
		<pubDate>Wed, 18 Nov 2009 19:08:40 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://www.flobee.net/?p=427</guid>
		<description><![CDATA[The OCS team blog has a post with a script for retrieving messages from the archiving database.  As is, the script will retrieve both the plain text version of the first message in a new conversation (as seen in the toast) and the RTF version that is displayed in the conversation window.  The [...]]]></description>
			<content:encoded><![CDATA[<p>The OCS team blog has a post with a <a href="http://communicationsserverteam.com/archive/2009/09/28/584.aspx">script</a> for retrieving messages from the archiving database.  As is, the script will retrieve both the plain text version of the first message in a new conversation (as seen in the toast) and the RTF version that is displayed in the conversation window.  The output of the report, however, doesn&#8217;t distinguish between the toast message and the RTF message, so it just looks like it is a duplicate message.</p>
<p>I have done some testing, and both versions are logged in the database even if you ignore the toast or decline the conversation.  I can&#8217;t think of a case where you will only have the toast logged and not the full message, so I have excluded all toast messages from my copy of the script.  To add this exclusion yourself, add <span class="flobeecode" id="codevariable">AND</span> <span class="flobeecode" id="codeplain">LcsLog.dbo.Messages.Toast</span> <span class="flobeecode" id="codevariable">IS NULL</span> to the SQL queries on lines 23 and 28 before the <span class="flobeecode" id="codestring">UNION</span> operator and before the <span class="flobeecode" id="codestring">ORDER BY</span> clause at the end, for a total of four times.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.flobee.net/exclude-toast-messages-from-ocs-archiving-report/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How to clear the mail attribute using PowerShell</title>
		<link>http://www.flobee.net/how-to-clear-the-mail-attribute-using-powershell/</link>
		<comments>http://www.flobee.net/how-to-clear-the-mail-attribute-using-powershell/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 16:09:58 +0000</pubDate>
		<dc:creator>Scott</dc:creator>
				<category><![CDATA[Exchange 2003]]></category>
		<category><![CDATA[Exchange 2007]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[inline code]]></category>

		<guid isPermaLink="false">http://www.flobee.net/?p=409</guid>
		<description><![CDATA[I have been struggling to delete the value in the mail attribute after a mailbox has been deleted.  Exchange populates the mail attribute when a mailbox is created (even though Exchange has no use for the attribute), but doesn&#8217;t clear the attribute when the mailbox is deleted.  With ADUC integration removed in Exchange [...]]]></description>
			<content:encoded><![CDATA[<p>I have been struggling to delete the value in the mail attribute after a mailbox has been deleted.  Exchange populates the mail attribute when a mailbox is created (even though Exchange has no use for the attribute), but doesn&#8217;t clear the attribute when the mailbox is deleted.  With ADUC integration removed in Exchange 2007, a quick way to know if an account has a mailbox is to look at the mail attribute.  But if removing a mailbox no longer clears that attribute, it is difficult know (just by looking at a user account in ADUC) if the account still has a mailbox.</p>
<p>Since Exchange doesn&#8217;t use the mail attribute, you can&#8217;t use the <span class="flobeecode" id="codekeyword">Set-Mailbox</span> attribute, especially if the mailbox is deleted anyway.  I tried using <span class="flobeecode" id="codekeyword">Set-User</span> with the <span class="flobeecode" id="codekeyword">-WindowsEmailAddress</span> parameter, but because the data type is <span class="flobeecode" id="codeplain">Microsoft.Exchange.Data.SmtpAddress</span>, setting the value to &quot;&quot; or <span class="flobeecode" id="codevariable">$null</span> doesn&#8217;t work because those aren&#8217;t properly formatted SMTP addresses.</p>
<p>So, I figured I needed to get away from any Exchange cmdlet.  I used PowerShell&#8217;s native support for ADSI to bind to the user object: <span class="flobeecode" id="codekeyword">New-Object</span> <span class="flobeecode" id="codeplain">DirectoryServices.DirectoryEntry</span> <span class="flobeecode" id="codestring">&quot;LDAP://UserDN&quot;</span>.  But you will get an error if you try to set the attribute to null (<span class="flobeecode" id="codevariable">$user</span><span class="flobeecode" id="codeplain">.mail = </span><span class="flobeecode" id="codevariable">$null</span>).  You can set it to an empty value (&quot;&quot;), but you will then get an error when you try to commit the change: <span class="flobeecode" id="codevariable">$user</span><span class="flobeecode" id="codeplain">.SetInfo()</span>.</p>
<p>How can you possibly clear this attribute, one that is so easy to do in ADUC just by deleting the value in it?  It is necessary to fall back to the <span class="flobeecode" id="codeplain">PutEx</span> method.  Using that will let you use the <span class="flobeecode" id="codeconstant">ADS_PROPERTY_CLEAR</span> constant (indicated by the numeric one in the first argument).  It has taken me days to finally get to this point, so hopefully this post will shorten that time for others trying to do the same thing.</p>
<pre class="brush:ps;gutter:false;collapse:false">
$user = Get-User "username"
$ldapDN = "LDAP://" + $user.distinguishedName
$adUser = New-Object DirectoryServices.DirectoryEntry $ldapDN
$adUser.PutEx(1, "mail", $null)
$adUser.SetInfo()
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.flobee.net/how-to-clear-the-mail-attribute-using-powershell/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
