<?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>Ionut Nica &#187; Powershell</title>
	<atom:link href="http://www.rivnet.ro/category/scripting/powershell/feed" rel="self" type="application/rss+xml" />
	<link>http://www.rivnet.ro</link>
	<description>Windows, Scripting, Virtualization, Cloud Computing - tricks for getting around in the world of Technology</description>
	<lastBuildDate>Tue, 31 Jan 2012 12:10:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Tracking vCenter VM and DB</title>
		<link>http://www.rivnet.ro/2012/01/tracking-vcenter-vm-and-db.html</link>
		<comments>http://www.rivnet.ro/2012/01/tracking-vcenter-vm-and-db.html#comments</comments>
		<pubDate>Tue, 31 Jan 2012 12:10:26 +0000</pubDate>
		<dc:creator>Ionut Nica</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[vCenter]]></category>
		<category><![CDATA[VMWARE]]></category>

		<guid isPermaLink="false">http://www.rivnet.ro/?p=504</guid>
		<description><![CDATA[It has been a while since I managed to do some writing on my blog, mostly because I&#8217;ve been busy with other Real Life events, and general lack of time. But now I&#8217;m here to share something that has been sitting in my drafts folder for a while. This one is about virtualization. 2010 and [...]]]></description>
			<content:encoded><![CDATA[<p>It has been a while since I managed to do some writing on my blog, mostly because I&#8217;ve been busy with other Real Life events, and general lack of time. But now I&#8217;m here to share something that has been sitting in my drafts folder for a while. This one is about virtualization.</p>
<p>2010 and 2011 were virtualization years for me, I worked on several projects in design, implementation, and I learned so much, that looking back I really get a feeling of accomplishment.<br />
I&#8217;ve also been a little &#8220;cutting edge&#8221;, non conservative with my designs some would say. I guess practice what you preach kind of stuck with me and I made it my mission to build reliable, self contained VMware environments, as much as possible.</p>
<p>As part of the design process, you always have to think about your management software</p>
<ul>
<li>Where do you put the pieces of software that help you manage the environment?</li>
<li>How do you ensure availability and SLA for these components to allow you to recover from failures?</li>
</ul>
<p>The answer to the first question can be:</p>
<p><strong>Option A:</strong> In a management cluster, dedicated to management software for the virtualization stack</p>
<ul>
<li>The advantage is you always know where the VMs are, if you have a failure there are 2 servers they can be on.</li>
<li>The disadvantage is you dedicate two physical boxes for this purpose, which can have a maximum utilization of around 40% for failover reasons.</li>
</ul>
<p><strong>Option B:</strong> Next to production machines</p>
<ul>
<li>The advantage is you don&#8217;t have to setup a management cluster, and you optimize resource utilization in your datacenter.</li>
<li>The disadvantage is that you lose &#8220;determinism&#8221;, the security of &#8220;I know on what server vCenter is sitting, so i don&#8217;t have to look for it&#8221;, if i get a cluster failure or worse.</li>
</ul>
<p>Well I&#8217;ve come up with two &#8220;tricks&#8221; that tackle the drawbacks of the second option, not knowing where your management servers are, making it a preferred choice if your environment does not warrant a dedicated management cluster just for that.</p>
<h3>#1 Track the movement of vCenter and vCenter DB using vCenter Alarms</h3>
<p>This one is a really easy way to keep track of your vCenter components. It works best combined with the second trick you will see below, mainly because it does not cover all scenarios but the advantage of this method is that the information is provided in real time.</p>
<p>What I am proposing is that you create an alarm in vCenter, that monitors for events that change the VMhost of your vCenter VM. These events are:</p>
<ol>
<li>VM is being migrated (manually)</li>
<li>VM is being migrated by DRS</li>
<li>VM is being restarted by HA on another host</li>
</ol>
<p>The third trigger will be hit and miss, it stands to reason, that if vCenter is not up to send the mail since it being restarted, you may or may not get the email, or you will get it after the fact. nevertheless it is good to have it there.</p>
<p>Below are the screenshots of how the alarm would look like:</p>
<p><a href="http://www.rivnet.ro/wp-content/uploads/2012/01/VM-conditions.png"><img class="aligncenter size-full wp-image-614" title="VM conditions" src="http://www.rivnet.ro/wp-content/uploads/2012/01/VM-conditions.png" alt="" width="737" height="471" /></a></p>
<p>On the advanced field put this condition in:</p>
<p><a href="http://www.rivnet.ro/wp-content/uploads/2012/01/trigger-conditions.png"><img class="aligncenter size-full wp-image-613" title="trigger-conditions" src="http://www.rivnet.ro/wp-content/uploads/2012/01/trigger-conditions.png" alt="" width="449" height="391" /></a></p>
<p>Then add some notification address or whatever you prefer</p>
<p><a href="http://www.rivnet.ro/wp-content/uploads/2012/01/Notification.png"><img class="aligncenter size-full wp-image-612" title="Notification" src="http://www.rivnet.ro/wp-content/uploads/2012/01/Notification.png" alt="" width="737" height="471" /></a></p>
<p>Save your alarm, and then try to migrate vCenter and see what happens. You should do this to the vCenter DB server aswell, and any components you feel you should know where they are, for troubleshooting purposes (VUM, Nexus 1000v Supervisor Modules, Management Appliances).</p>
<h3>#2 Check the vSphere host where vCenter is running using a scheduled script</h3>
<p>Another wasy to check where your vCenter components stay is using a scheduled PowerCLI script that runs once a day and sends you an email where vCenter VM and vCenter database are sitting (which vSphere host)</p>
<p>This script assumes following:</p>
<ol>
<li>vCenter VM name in inventory = vCenter VM hostname</li>
<li>vCenter is using separate database, if you don&#8217;t care about that, you can remove the references to the DB.</li>
<li>vCenter Database name in inventory = vCenter Database hostname or at least a cNAME with this name (e.g. RO-vcenter &gt; RO-vCenter-DB name, and alias in DNS)</li>
</ol>
<p>You can customize this by entering a CSV file of the names of the vcenter instances and their respective databases.</p>
<pre class="brush: powershell; title: ; notranslate"> #version 0.1
#initial release

Add-PSSnapin Vmware.VimAutomation.Core -ErrorAction:SilentlyContinue
Set-PowerCLIConfiguration -DefaultVIServerMode multiple -Confirm:$false
#Write-Host -ForegroundColor Yellow &quot;This script Generates a report detailing which host has the vCenter VM and vCenter DB VM`
#If you wish to cancel Press Ctrl+C,otherwise press Enter&quot;
#Read-Host

#using fqdn because certificates are issued using a FQDN
$vCenter = ('vcenter','vcenter2','vcenter3')

If ($global:DefaultVIServers -ne $null) {
	DisConnect-VIServer * -Force -Confirm:$false }
$vCenter | % {Connect-VIServer $_ -NotDefault:$false}

$Report = @()
$vCenters = $global:DefaultVIServers | % {
	$row = &quot;&quot; | select vCenterInstance,FrontendVMHost,DBVMName,DBVMHost
	$row.vCenterInstance = $_.Name
	$row.FrontendVMHost = (get-vm -Name $_.Name.Split(&quot;.&quot;)[0] -server $_.Name).VMHost
	#db is hostname + db
	$dbvm = &quot;$($_.Name.Split(&quot;.&quot;)[0])DB&quot;
	$DBVMName = ([System.Net.Dns]::GetHostByName($dbvm)).HostName.Split(&quot;.&quot;)[0]
	$row.DBVMName = $DBVMName
	$row.DBVMHost = (get-vm -Name $DBVMName* -server $_.Name).VMHost
	$Report += $row
}

$FileDate = get-date -Uformat &quot;%Y%m%d-%H%M%S&quot;
$Path = &quot;c:\temp\vsphere\&quot;
$File = &quot;$FileDate-vCenter-InfraLocation.csv&quot;
$Report | Export-Csv -NoTypeInformation -UseCulture &quot;$Path$File&quot;

$encoding = [System.Text.Encoding]::UTF8
#I made the convoluted out-string construct because the object cannot be serialized&quot;
$ReportBody = $null
$ReportBody += $Report | % { &quot;
`n
`n$($_.vCenterInstance)`n$($_.FrontendVMHost)`n$($_.DBVMName)`n$($_.DBVMHost)&quot;}$Body = &quot;&lt;/pre&gt;
&lt;div&gt;I'm the PowerCLI Magic Script. This is the list of your vCenter instances and their locations in the Infrastructure.
`
If you ever lose track of them, this email is the reminder. The latest update is from $FileDate
`
Below is the detailed information about each Instance:
`
`n`n`n`n`n`n$ReportBody`n`n
&lt;table border=&quot;`&amp;quot;1`&amp;quot;&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;vCenterInstance&lt;/td&gt;
&lt;td&gt;FrontendVMHost&lt;/td&gt;
&lt;td&gt;DBVMName&lt;/td&gt;
&lt;td&gt;DBVMHost&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div&gt;&quot;

Send-MailMessage -Smtpserver smtpserver -From 'admin_vmware@foo.com' -To 'vSphereAdministrators@foo.com' -Body $Body -Bodyashtml -Encoding $encoding -Subject &quot;vCenter Instances List&quot; -Attachments $Path$File</pre>
<div></div>
<h4>Learning points:</h4>
<p><strong>Line 11:</strong> This is where you define you vCenter server names, if you have more of them. I had 3 for example.</p>
<p><strong>Line 22 &amp; 27</strong>: This is where you perform a get-vm to find out the host where this VM is residing on</p>
<p>The rest of the script is just to cycle through all vCenter instances and create an email that it sends to a given email address.</p>
<p>Perhaps to some people this may seem unnecessary, as they may not have faced major outages, perhaps to some it may seem that these monitoring tricks are not enough to cover monitoring of all &#8216;outages&#8217; situations, but I find it is not worse than having a separate management cluster, with the added benefit of not having to deal with another separate management cluster.</p>
<p>C&amp;C as always is welcome</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.rivnet.ro%2F2012%2F01%2Ftracking-vcenter-vm-and-db.html&amp;title=Tracking%20vCenter%20VM%20and%20DB" id="wpa2a_2"><img src="http://www.rivnet.ro/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.rivnet.ro/2012/01/tracking-vcenter-vm-and-db.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Get List of Installed Windows Updates</title>
		<link>http://www.rivnet.ro/2011/09/get-list-of-installed-windows-updates-powershell.html</link>
		<comments>http://www.rivnet.ro/2011/09/get-list-of-installed-windows-updates-powershell.html#comments</comments>
		<pubDate>Fri, 02 Sep 2011 13:48:23 +0000</pubDate>
		<dc:creator>Ionut Nica</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[WSUS]]></category>
		<category><![CDATA[installed updates]]></category>
		<category><![CDATA[updates list]]></category>

		<guid isPermaLink="false">http://www.rivnet.ro/?p=520</guid>
		<description><![CDATA[This post falls into the category of note to self posts. A while back I researched the Internet for a way to get the list of installed updates on a computer. This is useful for those of us still using Microsoft WSUS without SCCM or some other Reporting Tool, because WSUS reports only the number [...]]]></description>
			<content:encoded><![CDATA[<p>This post falls into the category of note to self posts. A while back I researched the Internet for a way to get the list of installed updates on a computer.<br />
This is useful for those of us still using Microsoft WSUS without SCCM or some other Reporting Tool, because WSUS reports only the number of computers having or not having a patch installed/applicable, but not which ones.<br />
As of this date there are no Powershell cmdlets that let you get this information, no WMI query no nothing. You have to get it programatically, so I went along and created the following powershell code that creates a report.</p>
<pre class="brush: powershell; title: ; notranslate">$InputObject = Read-host -Prompt &quot;Insert Computername to get list of installed updates&quot;;
$Report = @()
$filename = &quot;$env:Temp\Report_$(get-date -Uformat &quot;%Y%m%d-%H%M%S&quot;).csv&quot;
$InputObject | % {
   $objSession = [activator]::CreateInstance([type]::GetTypeFromProgID(&quot;Microsoft.Update.Session&quot;,$_))
   $objSearcher= $objSession.CreateUpdateSearcher()
   $HistoryCount = objSearcher.GetTotalHistoryCount
   $colSucessHistory = $objSearcher.QueryHistory(0, $HistoryCount)
   Foreach($objEntry in $colSucessHistory | where {$_.ResultCode -eq '2'}) {
       $pso = &amp;quot;&amp;quot; | select Computer,Title,Date
       $pso.Title = $objEntry.Title
       $pso.Date = $objEntry.Date
       $pso.computer = $_
       $Report += $pso
       }
   $objSession = $null
   }
}
$Report | where { $_.Title -notlike 'Definition Update*'} | Export-Csv $filename -NoTypeInformation -UseCulture
ii $filename</pre>
<p>Once you run this report and have an csv viewer installed (excel for example( it will open up the file so you can review it. When exporting I did a filter to remove MS Forefront definition updates as it is pretty irrelevant most of the time, you use other tools to manage Forefront definitions.</p>
<h2>Learning Points</h2>
<p><strong>Line 05</strong> &#8211; This line creates and instance of the Windows Update API. What is neat about this function is the fact that can create an instance of the API and connect to a remote computer, notice the &#8220;$_&#8221; at the end of the line.</p>
<p><strong>Line 09</strong> &#8211; In this line after searching the entire history we filter out all but successful updates. Yes it would be nice to do that in the actual search, but I don&#8217;t know if it is possible. So I resorted to filtering out only successful result codes.</p>
<p>Below is a table with possible values. This can be useful if you want to generate a report based on the result code</p>
<table style="width: auto;" border="0" align="left">
<tbody>
<tr>
<td style="text-align: left;">Result Code</td>
<td style="text-align: left;">Update Status</td>
</tr>
<tr>
<td style="text-align: left;">0</td>
<td style="text-align: left;">Not Started</td>
</tr>
<tr>
<td style="text-align: left;">1</td>
<td style="text-align: left;">In Progress</td>
</tr>
<tr>
<td style="text-align: left;">2</td>
<td style="text-align: left;">Successful</td>
</tr>
<tr>
<td style="text-align: left;">3</td>
<td style="text-align: left;">Incomplete</td>
</tr>
<tr>
<td style="text-align: left;">4</td>
<td style="text-align: left;">Failed</td>
</tr>
<tr>
<td style="text-align: left;">5</td>
<td style="text-align: left;">Aborted</td>
</tr>
</tbody>
</table>
<div style="clear: both; font-size: 0; line-height: 0;">&nbsp;</div>
<p>That&#8217;s about it with getting the list of installed updates, the bit of code above can be easily integrated to run across a large number of computers. Thanks for reading and feedback.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.rivnet.ro%2F2011%2F09%2Fget-list-of-installed-windows-updates-powershell.html&amp;title=Get%20List%20of%20Installed%20Windows%20Updates" id="wpa2a_4"><img src="http://www.rivnet.ro/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.rivnet.ro/2011/09/get-list-of-installed-windows-updates-powershell.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dismount Recovery Storage Group using Exchange 2007 Shell</title>
		<link>http://www.rivnet.ro/2010/11/dismount-recovery-storage-group-using-exchange-2007-shell.html</link>
		<comments>http://www.rivnet.ro/2010/11/dismount-recovery-storage-group-using-exchange-2007-shell.html#comments</comments>
		<pubDate>Sun, 14 Nov 2010 22:02:10 +0000</pubDate>
		<dc:creator>Ionut Nica</dc:creator>
				<category><![CDATA[Mailbox Recovery]]></category>
		<category><![CDATA[Management Shell]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[data recovery]]></category>
		<category><![CDATA[Exchange 2007]]></category>
		<category><![CDATA[Exchange Management Shell]]></category>
		<category><![CDATA[Recovery Storage Group]]></category>
		<category><![CDATA[RSG]]></category>

		<guid isPermaLink="false">http://www.rivnet.ro/?p=413</guid>
		<description><![CDATA[Dismounting the RSG from and Exchange Mailbox server is the last step after you have recovered data you needed. I would like to stress here that my experience tells me this is the step when you will encounter issues, not necesarily issues with the process itself but mostly with the GUI interface. I&#8217;ve spent a [...]]]></description>
			<content:encoded><![CDATA[<p>Dismounting the RSG from and Exchange Mailbox server is the last step after you have recovered data you needed. I would like to stress here that my experience tells me this is the step when you will encounter issues, not necesarily issues with the process itself but mostly with the GUI interface. I&#8217;ve spent a lot of time trying to figure out which a RSG won&#8217;t dismount, when the GUI reported success. So I have come up with a script that does this using exchange management shell, which gives you a little more control and additional debugging information.</p>
<p>Here is what you will need to accomplish this:</p>
<ul>
<li>Exchange Server Administrator Rights where the RSGs are located.</li>
<li>Exchange Management Shell since this entire procedure is best done using powershell scripting.</li>
<li>Run the script as Administrator to avoid errors due to enabled UAC</li>
</ul>
<h3>The Script</h3>
<pre class="brush: powershell; title: ; notranslate">#Dismount DB, Remove, DB, Remove Storage Group
$DB_in_RSG = Get-MailboxDatabase -Server &lt;ENTERSERVER&gt; | where {$_.Recovery -like '*true*'}
Write-Host -ForegroundColor Green &quot;The Database in the RSG ($($DB_in_RSG.Name)) will be Dismounted. Press Ctrl+C to cancel or Enter to continue&quot;
Read-Host
$DB_in_RSG | Dismount-Database -Verbose -Debug

Write-Host -ForegroundColor Green &quot;The Database in the RSG will be Removed. Press Ctrl+C to cancel or Enter to continue&quot;
Read-Host
$DB_in_RSG | Remove-MailboxDatabase -Verbose -Debug

#Now deleting the files of the database
$SG_Path = (Get-StorageGroup $DB_in_RSG.StorageGroup).SystemFolderPath
Write-Host -ForegroundColor Green &quot;The actual DB files will be removed (stored in $SG_Path). Please check previous steps completed successfully before continuing. Press Ctrl+C to cancel or Enter to continue.&quot;
Read-Host
get-item $SG_Path | del -Force -Recurse -Verbose -Debug

#Now removing storage group
Write-Host -ForegroundColor Green &quot;The RSG will be Removed. Press Ctrl+C to cancel or Enter to continue&quot;
Read-Host
Remove-StorageGroup -Identity $DB_in_RSG.StorageGroup -Verbose –Debug</pre>
<h3>Learning Points</h3>
<p>There are a few steps you need to do:</p>
<ol>
<li>Grab the RSG (there is only one per server) &#8211; stored in the script in <strong>$DB_in_RSG</strong></li>
<li>You dismount the database from the server using <strong>Dismount-Database</strong> cmdlet.</li>
<li>After disomunting the database you remove the Database using <strong>Remove-MailboxDatabase</strong> cmdlet. This will just remove the DB from Exchange, the files will remain on the file system.</li>
<li>The actual files on the file system get removed using the path from variable <strong>$SG_Path.</strong> Use <strong>del</strong> cmdlet with <strong>-force -recurse</strong> to bypass any confirmation prompts.</li>
<li>The last step is removing the Recovery Storage Group from the Exchange. The commandlet for this is <strong>Remove-StorageGroup</strong>.</li>
</ol>
<p>That&#8217;s about it, pretty easy actually. Although this script is the last in the series I reccomend you actually run this before anything, before mounting the RSG or at least do a check to see if a RSG is already mounted.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.rivnet.ro%2F2010%2F11%2Fdismount-recovery-storage-group-using-exchange-2007-shell.html&amp;title=Dismount%20Recovery%20Storage%20Group%20using%20Exchange%202007%20Shell" id="wpa2a_6"><img src="http://www.rivnet.ro/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.rivnet.ro/2010/11/dismount-recovery-storage-group-using-exchange-2007-shell.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Restore a mailbox in the Recovery Storage Group</title>
		<link>http://www.rivnet.ro/2010/11/restore-a-mailbox-in-the-recovery-storage-group.html</link>
		<comments>http://www.rivnet.ro/2010/11/restore-a-mailbox-in-the-recovery-storage-group.html#comments</comments>
		<pubDate>Sun, 07 Nov 2010 17:48:10 +0000</pubDate>
		<dc:creator>Ionut Nica</dc:creator>
				<category><![CDATA[Mailbox Recovery]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Exchange 2007]]></category>
		<category><![CDATA[Exchange Management Shell]]></category>
		<category><![CDATA[export-mailbox]]></category>
		<category><![CDATA[get-mailbox]]></category>

		<guid isPermaLink="false">http://www.rivnet.ro/?p=421</guid>
		<description><![CDATA[Finally I managed to find some more time about posting the next bits of the Exchange mailbox recovery process. Last post we discussed how to mount the database into the RSG. This time we will be discussing how to restore a user&#8217;s mailbox in the original mailbox location and how to restore the mailbox data [...]]]></description>
			<content:encoded><![CDATA[<p>Finally I managed to find some more time about posting the next bits of the Exchange mailbox recovery process. Last post we discussed how to mount the database into the RSG. This time we will be discussing how to restore a user&#8217;s mailbox in the original mailbox location and how to restore the mailbox data to another temporary mailbox and exporting that out of the temporary mailbox.</p>
<p>Here is what you will need to accomplish this:</p>
<ul>
<li>Exchange Server Administrator Rights where the mailbox(es) are located.</li>
<li>Full mailbox access for exporting emails out of the temp mailbox I was talking about</li>
<li>Exchange Management Shell since this entire procedure is best done using powershell scripting.</li>
<li>Obviously free space both on the Database disk aswell as disk space where the PST file will be saved.</li>
</ul>
<h3>The Script</h3>
<pre class="brush: powershell; title: ; notranslate">#Parameters Section
param (
 [parameter(Mandatory = $true)]
 [string]$paramRestoredUser
)

cls
#Restore mailbox section
$Filter = &quot;SamAccountName -like '$paramRestoredUser'&quot;
$SourceAlias = Get-Mailbox -Filter $Filter -IgnoreDefaultScope

If ($SourceAlias -eq $null) {
 Write-Host -foregroundcolor Red &quot;No Mailbox for SamAccountName $paramRestoredUser found.Script will quit&quot;
exit
 }

$RSG_DB = Get-MailboxDatabase -Server $SourceAlias.ServerName | where {$_.Recovery -like '*true*'}
if ($RSG_DB -eq $null) {
 Write-Host -ForegroundColor Red &quot;No RSG was found on $($SourceAlias.ServerName). Script will quit now!&quot;
 exit }

$TargetAlias = Get-Mailbox e2k7_Restore_MBX
Write-Host -ForegroundColor Green &quot;Input the date of the restored mailbox:&quot;
$RestoreDate = Read-Host

$TargetFolder = &quot;$($SourceAlias)_$RestoreDate&quot;
Restore-Mailbox -Identity $TargetAlias.Alias -RSGMailbox $SourceAlias.ExchangeGuid -RSGDatabase $RSG_DB -TargetFolder $TargetFolder -BadItemLimit 1000 -Verbose -Debug -Confirm -ValidateOnly

echo &quot;-ValidateOnly switch from the command above is removed. Please check no errors occured above and everything is configured properly. Press Enter to continue CTRL+C to cancel the script!&quot;
Read-Host
Restore-Mailbox -Identity $TargetAlias.Alias -RSGMailbox $SourceAlias.ExchangeGuid -RSGDatabase $RSG_DB -TargetFolder $TargetFolder -BadItemLimit 1000 -Verbose -Debug -Confirm

#building an excluded folders list, just in case we did another restore and the previous content was not deleted
$IncludedFolders = $TargetFolder
$ExclFoldersList = @()
$ExcludedFolders = Get-MailboxFolderStatistics $TargetAlias | where-object { $_.FolderPath -notlike &quot;*$($IncludedFolders)*&quot;} | Select-Object FolderPath | foreach-object {
 $ExclFoldersList += $_.FolderPath }
$ExclFoldersList = ([string]::join(&quot;,&quot;,$ExclFoldersList)).Replace(&quot;/&quot;,&quot;\&quot;)

$UserName = $TargetAlias
$PSTPath = &quot;Q:\UserPersonalFolders&quot;
&quot;Excluded folders list: $ExclFoldersList&quot;
Read-Host
export-Mailbox -Identity $UserName.SamAccountName -BadItemLimit 1000 -DeleteContent $True -PSTFolderPath $PSTPath -ExcludeFolders $ExclFoldersList</pre>
<h3>The details for the Script</h3>
<p>First the script gathers data about the restored mailbox, and from that info the Recovery Storage Group (<strong>$SourceAlias</strong>). It also needs a target mailbox, where the restored data will be stored (<strong>$TargetAlias</strong>) (needless to say I did in a &#8220;forest friendly way, using -Filter cmdlet looking up the given SamAccountName). The data will be moved from the mailbox in the RSG into the <strong>$TargetAlias</strong> mailbox. It will be placed in a folder, named with the date of the restored data (<strong>$RestoreDate</strong>). Restoring the data is done with this command:</p>
<pre class="brush: powershell; title: ; notranslate">Restore-Mailbox -Identity $TargetAlias.Alias -RSGMailbox $SourceAlias.ExchangeGuid -RSGDatabase $RSG_DB -TargetFolder $TargetFolder -BadItemLimit 1000 -Verbose -Debug -Confirm -ValidateOnly</pre>
<p>Now we want to export the data from the <strong>$TargetAlias</strong> into a PST file. This is easy to do via the <strong>Export-Mailbox </strong>cmdlet. The problem appears when you do for instance multiple exports in the same target mailbox and then a mass export, or just have left old data in the target mailbox. You do get data separated into folders, if your <strong>$TargetFolder</strong> name is unique, but the <strong>Export-Mailbox</strong> cmdlet cannot export data based on this information (it can only do some filtering (date,content,subject)  and I believe it is resource intensive). What Export-Mailbox does have is the  &#8220;<strong>-Excludefolders</strong>&#8221; parameter which lets you not export certain data.</p>
<p>The trick I came up with was to scan the <strong>$TargetAlias</strong> mailbox for foldernames (I used <strong>Get-MailboxFolderStatistics</strong> for that) and build a list of the folders that did not contain the value I entered in the  <strong>$TargetFolder</strong> variable upon restore. Besides that you also have to do some parsing of the output from get mailboxfolderstatistics into something <strong>Export-Mailbox</strong> understands. This is what I did:</p>
<pre class="brush: powershell; title: ; notranslate">$IncludedFolders = $TargetFolder
$ExclFoldersList = @()
$ExcludedFolders = Get-MailboxFolderStatistics $TargetAlias | where-object { $_.FolderPath -notlike &quot;*$($IncludedFolders)*&quot;} | Select-Object FolderPath | foreach-object {
 $ExclFoldersList += $_.FolderPath }
$ExclFoldersList = ([string]::join(&quot;,&quot;,$ExclFoldersList)).Replace(&quot;/&quot;,&quot;\&quot;)</pre>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 645px; width: 1px; height: 1px;">downtime romtelecom</div>
<p>In the end I just ran the Export-Mailbox on the target mailbox, specifying the excluded files and that was that.</p>
<p>The whole process is pretty easy, the actual restore is done in a one liner (Restore-Mailbox), but as you can see error checking and failproofing the script make up the rest of the work. Hope you enjoy this, next up is how to dismount a RSG, the scripted &#8220;clean-way&#8221;.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.rivnet.ro%2F2010%2F11%2Frestore-a-mailbox-in-the-recovery-storage-group.html&amp;title=Restore%20a%20mailbox%20in%20the%20Recovery%20Storage%20Group" id="wpa2a_8"><img src="http://www.rivnet.ro/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.rivnet.ro/2010/11/restore-a-mailbox-in-the-recovery-storage-group.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Restoring mailboxes in Exchange 2007 (part 1)</title>
		<link>http://www.rivnet.ro/2010/07/restoring-a-mailbox-in-exchange2007-part-1-of-3.html</link>
		<comments>http://www.rivnet.ro/2010/07/restoring-a-mailbox-in-exchange2007-part-1-of-3.html#comments</comments>
		<pubDate>Thu, 15 Jul 2010 20:30:01 +0000</pubDate>
		<dc:creator>Ionut Nica</dc:creator>
				<category><![CDATA[Mailbox Recovery]]></category>
		<category><![CDATA[MS Exchange 2007]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[data recovery]]></category>
		<category><![CDATA[Exchange 2007]]></category>
		<category><![CDATA[Recovery Storage Group]]></category>
		<category><![CDATA[RSG]]></category>

		<guid isPermaLink="false">http://www.rivnet.ro/?p=419</guid>
		<description><![CDATA[Lately I&#8217;ve been doing a number of mailbox restore procedures on Exchange 2007, so I thought it would be a good idea to make my own posts about it (yes it involves scripting), because things are not always as straightforward as MS or TechNet say it is. This is going to be a multi-part post: [...]]]></description>
			<content:encoded><![CDATA[<p>Lately I&#8217;ve been doing a number of mailbox restore procedures on Exchange 2007, so I thought it would be a good idea to make my own posts about it (yes it involves scripting), because things are not always as straightforward as MS or TechNet say it is. This is going to be a multi-part post: Create the RSG and mount the DB to be restored, Restore mailbox(es), Remove the restored DB and RSG. Before you think about it I&#8217;m going to answer it for you:</p>
<p style="padding-left: 30px;">Q: But why don&#8217;t we use the nice GUI Tool from Exchange Management Console (Extra.exe) and do it from there, &#8220;we don&#8217;t need no scripting&#8221;?</p>
<p style="padding-left: 30px;">A: My experience tells me the scripted method is safer and works &#8220;as expected&#8221; unlike the GUI, which says it did something, when it didn&#8217;t (I&#8217;ve spent days trying to figure out why a RSG Database won&#8217;t actually dismount when the GUI said: &#8220;Completed Successfully&#8221;.</p>
<p>OK, let&#8217;s get on with it. All that I am about to explain requires <strong>Exchange Administrator</strong> privileges on the Exchange servers.</p>
<p>We will be creating a Recovery Storage Group, this is the first step in the restore process. To create the RSG you need following:</p>
<ul>
<li>Adequate disk-space to restore the mailbox database, locally on the Exchange Server where the DB was residing</li>
<li>Exchange Management Shell running as Administrator (especially on CCR clusters)</li>
<li>No other Recovery Storage Group already created on that server with an existing RSG database (you can only have 1 RSG with 1 DB in the RSG). It is best to remove any previous RSG completely then recreate it for your needs.</li>
<li>Specific information like which DB to link to the RSG and the list of mailboxes to restore.</li>
</ul>
<p>Creating a Recovery Storage Group can be as easy as this:</p>
<pre class="brush: powershell; title: ; notranslate">New-StorageGroup -Server &lt;MBX Role Server Name&gt; -Name &lt;StorageGroup Name&gt; -LogFolderPath &lt;Logs Folder&gt; -SystemFolderPath &lt;SystemFiles Path&gt; -Recovery -Verbose</pre>
<p>The command is very similar to creating a new SG, except for the <em>-Recovery</em> switch, designating it as a Recovery Storage Group. I added the -Verbose switch so you can see what is going on behind the scenes.</p>
<pre class="brush: powershell; title: ; notranslate">New-MailboxDatabase -MailboxDatabaseToRecover &lt;Mailbox Name&gt; -StorageGroup &lt;Recovery Storage Group Name&gt; -EdbFilePath &lt;path to store edb file&gt; -Verbose</pre>
<p>Here it is just as easy as creating a new mailbox database, only you are creating it in the recovery storage group you created with the previous command. The <strong>key </strong>thing to remember here is that the value of the &#8220;MailboxDatabaseToRecoverParameter&#8221; must be the exact same name of the mailboxDB of which you want to recover from. <strong>If the name is different</strong> you will not be able to run any restore commands, because it will not be able to find any mailboxes when it searches the recovered database.</p>
<h3>A working script for creating the RSG</h3>
<p>Below I&#8217;m sharing with you a working snippet that should help in creating a recovery storage group and DB. In short here is what the code does:</p>
<p>Using a given UserPrincipalName&#8230;</p>
<ul>
<li>Attempts to retrieve the mailbox for the UPN (it is a &#8220;forest friendly&#8221; coding for retrieving the mailbox). If it fails it quits</li>
<li>Checks if a folder structure for placing, logs, system files and the edb file exists (I used a location called d:, use a variable if you like).</li>
<li>If folders already exist, it will quit, otherwise it will create a folder with the MDB name, and logs and edb subfolders,</li>
<li>Next it checks if a Recovery Storage Group already exists, unless you cancel the script it will continue to use this RSG, with the given details. Otherwise it will create a RSG on its own.</li>
<li>It will then create a mailbox database where you / your backup admin will restore your exchange backup.</li>
</ul>
<pre class="brush: powershell; title: ; notranslate">﻿$MBX_UPN = Read-Host
$Filter = &quot;UserPrincipalName -like '$MBX_UPN'&quot;
$SourceMBX =  get-mailbox -IgnoreDefaultScope -Filter $Filter
If ($SourceMBX -eq $null) {
	Write-Host -foregroundcolor Red &quot;No Mailbox for $MBX_ID found`nScript will Quit&quot;
	exit }
Write-Host -ForegroundColor Green &quot;Source Mailbox is`n $SourceMBX&quot;

$LinkedMDB = Get-MailboxDatabase -Identity $SourceMBX.Database
Write-Host -ForegroundColor Green &quot;Ok, Database ($($LinkedMDB.StorageGroup.Name)) is grabbed, now creating RSG Folders and RSG`nPress Enter to continue or Ctrl+C to Cancel&quot;
Read-Host

#Checking if the RSG folders already exist, if not attempt to create them
If ((Test-Path &quot;d:\$($LinkedMDB.StorageGroup.Name)&quot;)) {
 Write-Host -ForegroundColor Red &quot;Folder already exists. Please remove d:\$($LinkedMDB.StorageGroup.Name) before running this script again.`nScript will quit&quot;
 exit
 }
$SysPath = New-Item -Type Directory -Path d: -Name $LinkedMDB.StorageGroup.Name | Get-Item
If ((Test-path $SysPath)) {
 $DBPath = New-Item -Type Directory -Path $SysPath -Name DB | Get-Item
 $LogsPath = New-Item -Type Directory -Path $SysPath -Name Logs | Get-Item
 }
#If folders were created successfully we can continue
If ((Test-path $SysPath) -and (Test-path $DBPath) -and (Test-path $LogsPath)) {
 #Checking if RSG already exists
$RSG_check = Get-StorageGroup -Server $LinkedMDB.ServerName | where {$_.Recovery -like &quot;True&quot;}
 If ($RSG_check -ne $null) {
 Write-Host -ForegroundColor Magenta &quot;A RSG was found on $($RSG_check.ServerName). Here are RSG Details:&quot;
 $RSG_Check | select-object Name,Identity,Recovery,LogFolderPath,SystemFolderPath | fl
 Write-Host -ForegroundColor Magenta &quot;To use this RSG Press Enter, to cancel Press Ctrl+C&quot;
 Read-Host
 }
 Else {
 Write-Host -ForegroundColor Green &quot;Now creating Recovery Storage Group...&quot;
 New-StorageGroup -Server $LinkedMDB.Server -Name &quot;Recovery Storage Group&quot; -LogFolderPath $LogsPath.FullName -SystemFolderPath $SysPath.FullName -Recovery -Verbose
 }
 Write-Host -ForegroundColor Green &quot;OK! No RSG found. Now creating RSG Database...&quot;
 New-MailboxDatabase -MailboxDatabaseToRecover $LinkedMDB.AdminDisplayName -StorageGroup &quot;$($LinkedMDB.ServerName)\Recovery Storage Group&quot; -EdbFilePath &quot;$($DBPath.FullName)\$($LinkedMDB.Name).edb&quot; -Verbose
 }
Else {
 Write-Host -ForegroundColor Red &quot;Could not Create folder or folder structure in d:\$($LinkedMDB.StorageGroup.Name). Check messages above for errors! Script will quit.&quot;
 exit
 }</pre>
<p>This is about it with creating a Recovery Storage Group, it is actually not difficult, just remember to name the MDB inside the RSG with the same name as the source MDB (this was also required on Exchange 2003, as far as I know). Also you cannot have more than one RSG per Maibox Server, it is best to remove any RSG you have after you are finished recovering data. Next post we will discuss how to restore data from a MDB and how to remove the RSG.</p>
<p>As always I value your feedback and hope you found this post useful.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.rivnet.ro%2F2010%2F07%2Frestoring-a-mailbox-in-exchange2007-part-1-of-3.html&amp;title=Restoring%20mailboxes%20in%20Exchange%202007%20%28part%201%29" id="wpa2a_10"><img src="http://www.rivnet.ro/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.rivnet.ro/2010/07/restoring-a-mailbox-in-exchange2007-part-1-of-3.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Log Battery and Power Levels using Powershell</title>
		<link>http://www.rivnet.ro/2010/05/log-battery-and-power-levels-using-powershell.html</link>
		<comments>http://www.rivnet.ro/2010/05/log-battery-and-power-levels-using-powershell.html#comments</comments>
		<pubDate>Sun, 09 May 2010 14:02:48 +0000</pubDate>
		<dc:creator>Ionut Nica</dc:creator>
				<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Windows 7]]></category>
		<category><![CDATA[Battery]]></category>
		<category><![CDATA[Energy]]></category>
		<category><![CDATA[WMI classes]]></category>

		<guid isPermaLink="false">http://www.rivnet.ro/?p=385</guid>
		<description><![CDATA[This is a let&#8217;s say lighter post, I came up while trying to compare battery life of my laptop and some buddies of mine. I wanted to know, how fast my battery depleted using different settings, use profile and power saving modes. Then I did some digging around Microsoft&#8217;s MSDN site, and I found some [...]]]></description>
			<content:encoded><![CDATA[<p>This is a let&#8217;s say lighter post, I came up while trying to compare battery life of my laptop and some buddies of mine. I wanted to know, how fast my battery depleted using different settings, use profile and power saving modes. Then I did some digging around Microsoft&#8217;s MSDN site, and I found some interesting WMI classes, that apparently provide a lot of &#8220;power related data&#8221;. I also wanted to have a way to log this data, and that&#8217;s how I ended up learning how to create a new event-log file and write data to it to use that as a log. So this is what I will try to show: <strong>get power related data</strong> and <strong>write it to the Event-Log</strong>.</p>
<h3>&#8220;Energy&#8221; Related WMI Classes</h3>
<p>Here are a few interesting classes I stumbled upon. Some of them are only available under Windows7 probably also Vista, but I&#8217;m not sure.</p>
<ul>
<li><strong>WmiMonitorBrightness</strong> &#8211; gives information about monitor brightness. For example these line give the max. &#8220;value&#8221; and current value of brightness</li>
</ul>
<pre class="brush: powershell; title: ; notranslate">$MaxBrightness = get-wmiobject -class WmiMonitorBrightness -Namespace root/wmi).level | measure-object -Maximum).maximum
$CrtBrightness = &quot;{0:P0}&quot; -f ((get-wmiobject -class WmiMonitorBrightness -Namespace root/wmi).CurrentBrightness/$MaxBrightness)</pre>
<ul>
<li><strong>Win32_PowerPlan</strong> &#8211; provides information and identifiers about the powerplans defined. In this class ALL powerplans are defined, and just the active plan has an &#8220;IsActive&#8221; flag attached it, here&#8217;s how to get it:</li>
</ul>
<pre class="brush: powershell; title: ; notranslate">$powerplan = (Get-WmiObject -Class win32_powerplan -Namespace 'root/cimv2/power' | where {$_.IsActive -eq $true}).ElementName</pre>
<ul>
<li><strong>Win32_Processor</strong> &#8211; gets information about the CPU (I was interested in the CPU load for statistical purposes). This one was pretty easy to find, the value was written in plain sight. Take a look:</li>
</ul>
<pre class="brush: powershell; title: ; notranslate">$cpu = (Get-WmiObject Win32_Processor).LoadPercentage</pre>
<ul>
<li><strong>Win32_Battery</strong> &#8211; Provides information about the battery itself (estimated time, remaining load, power status). Running &#8220;<strong>Get-WmiObject -Class Win32_Battery | gm&#8221;</strong> take a closer look at these members:
<ul>
<li><strong>BatteryStatus</strong> &#8211; this will toggle between &#8217;1&#8242; meaning on Battery and &#8217;2&#8242; meaning on AC Power</li>
<li><strong>EstimatedRuntime</strong> &#8211; this will be the number of minutes running on battery, as the OS estimates it, and if you get a  very high value (tens of thousands) when you plug the AC Power, it means the battery is charging</li>
<li><strong>EstimatedChargeRemaining</strong> &#8211; percentage-wise representation of battery charge remaining</li>
</ul>
</li>
</ul>
<h3>Powershell + Event-Log &#8220;101&#8243;</h3>
<p>I used this battery and power experiment to learn more about working and writing data to the Event-Log. I wanted to create a new &#8220;Event-Log&#8221; in Windows (windows 7 as you probably know allows for a lot of application logs) and then write events to it. Then at any point you can export the Event-log to csv. The following creates an Event-Log, with the name &#8220;BatteryMonitor&#8221; from the Information category (for my uses &#8220;Source&#8221; was not needed but it is a required parameter:</p>
<pre class="brush: powershell; title: ; notranslate">New-EventLog -Source BattMon -LogName BatteryMonitor -CategoryResourceFile Information</pre>
<p>You can also check if an Event-log is created exists you can use this scriptlet (the answer lies in WMI this time, I didn&#8217;t find a cmdlet that does it faster):</p>
<pre class="brush: powershell; title: ; notranslate">(get-wmiobject -class &quot;Win32_NTEventlogFile&quot; | where {$_.LogFileName -like 'BatteryMonitor'} | measure-object ).count -eq '1'</pre>
<p>Finally here&#8217;s how to write to the event-log, a new event. This bit I used in a script to mark the execution of the script in the event-log:</p>
<pre class="brush: powershell; title: ; notranslate">Write-EventLog -LogName BatteryMonitor -Source BattMon -EventID 65533 -Message 'Starting new Execution of BatteryCharge Monitor Script. The script will pump here CSV values. Values are listed in this order, as CSV: PowerPlan,PowStatMsg,ChargeRemMsg,RemTimeMsg,RAM,CPU,CrtBrightness' -EntryType Information -ComputerName $env:computername -ErrorAction:SilentlyContinue</pre>
<p>So that is about it, as usual I tried to tie all of these scriptlets into a usable script, you can download it from <a href="http://www.rivnet.ro/wp-content/uploads/2010/05/win7_battlevel.zip" target="_blank">here</a>.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.rivnet.ro%2F2010%2F05%2Flog-battery-and-power-levels-using-powershell.html&amp;title=Log%20Battery%20and%20Power%20Levels%20using%20Powershell" id="wpa2a_12"><img src="http://www.rivnet.ro/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.rivnet.ro/2010/05/log-battery-and-power-levels-using-powershell.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Removing specific message(s) from multiple Exchange 2007 mailboxes</title>
		<link>http://www.rivnet.ro/2010/02/removing-specific-messages-from-multiple-exchange-2007-mailboxes.html</link>
		<comments>http://www.rivnet.ro/2010/02/removing-specific-messages-from-multiple-exchange-2007-mailboxes.html#comments</comments>
		<pubDate>Sat, 20 Feb 2010 23:55:23 +0000</pubDate>
		<dc:creator>Ionut Nica</dc:creator>
				<category><![CDATA[Management Shell]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[add-mailboxpermissions]]></category>
		<category><![CDATA[Exchange Management Shell]]></category>
		<category><![CDATA[export-mailbox]]></category>
		<category><![CDATA[get-mailbox]]></category>
		<category><![CDATA[get-messagetrackinglog]]></category>
		<category><![CDATA[group-object]]></category>
		<category><![CDATA[remove-mailboxpermissions]]></category>

		<guid isPermaLink="false">http://www.rivnet.ro/?p=189</guid>
		<description><![CDATA[I seem to be doing quite a bit Powershell scripting these days, and some of related to MS Exchange 2007. One issue we had recently was that loose permissions on Distribution Lists with hundreds of users + too much spare time for some users generated a lot of unwanted message traffic. I don&#8217;t want to [...]]]></description>
			<content:encoded><![CDATA[<p>I seem to be doing quite a bit Powershell scripting these days, and some of related to MS Exchange 2007. One issue we had recently was that loose permissions on Distribution Lists with hundreds of users + too much spare time for some users generated a lot of unwanted message traffic. I don&#8217;t want to discuss prevention measures like restricting who can send emails to big DLs or using Microsoft AD RMS to restrict what can be done with emails. Our goal here is to clean up the mess <img src='http://www.rivnet.ro/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<p>Essentially you can get some info about the message and mailboxes, and use it with Export-mailbox to remove the data. That is how I  initially found this <a href="http://msexchangeteam.com/archive/2006/12/18/431934.aspx" target="_blank">link</a>,  but what is not written there is that you   need to have all the  prerequisites for running export-mailbox, and also  running it on hundreds of mailboxes may take a while. I decided to do  it my way,by building on what I found on that blog.</p>
<p>This is &#8220;Mass Remove message(s) from mailboxes &#8211; My Way&#8221;.Depending on your situation you can apply these steps  multiple times:</p>
<ol>
<li>Identify the message that started it all</li>
<li>Track the message on the Exchange Servers and compile a list of unique recipients of the message.</li>
<li>Remove the message from the offended mailboxes (there may be special requirements to perform the task, see <a href="http://msexchangeteam.com/archive/2007/04/13/437745.aspx" target="_blank">here</a>)</li>
</ol>
<h3>Identify Message</h3>
<p>Getting the information should be pretty easy, someone probably forwarded you the copy of the message(s) to be dealt with. You want to get this info as a minimum: <strong><em>subject,sender,date and time</em></strong><em> message(s) was/were sent. </em>When you have enough info, open the <em>Exchange Management Console &gt; Tools  &gt;  Message Tracking</em> and from there identify which of the events represent the time the message originally arrived on the Transport Servers. For that event grab the  &#8220;MessageID&#8221;  Value. We will use this in the following steps to find all events relating to that specific messageID.</p>
<h3>Track Message</h3>
<p>Assuming the worst case scenario you have to do tracking across all Exchange Transport Servers, the speed of the process depends on how close to your Exchange  Transport Role Servers you are running the tracking.  I suggest you make sure this process runs in the same LAN as the Exchange, especially the export-mailbox part. Anyhow, to get all messages sent by &#8220;baduser@foo.com&#8221; across all transport servers in your Exchange run this:</p>
<pre class="brush: powershell; title: ; notranslate">$TrackingLogResults = get-transportserver | where {$_.Name -like &quot;&lt;optional filter&gt;&quot;} | foreach-object  {Get-MessageTrackingLog -EventId DELIVER -MessageID &lt;MessageID from Step1&gt; -ResultSize Unlimited -server $_}</pre>
<ul>
<li><strong><em>Get-TransportServer</em></strong> gives you all the transport servers in the organization</li>
<li><em>Where </em>clause filters the servers list, you can leave it out, it is helpful if your HUB transport servers are named in a specific way, and you know the message did not leave the organization, so you can exclude a search on the Edge Servers.</li>
<li><strong><em>Foreach-Object </em></strong>cycles through all servers and performs the search</li>
<li><strong><em>Get-MessageTrackingLog</em></strong> searches each transport server tracking log for DELIVER Events that correspond to messages with that specific MessageID. It returns unlimited results. The server that is being searched is piped from the Foreach cmdlet.</li>
<li>If you run the last cmdlet without the EventID filter, you will get lots of other EventID&#8217;s like fail,send,receive,routing,expand. You just need deliver, DELIVER is important because it basically says &#8220;OK, this message passed all of my checks I am now sending it to the Mailbox Server so it can submit it to the mailbox store&#8221;, so you get a list of just the actually affected mailboxes.</li>
</ul>
<p>This may take a while to run. Once it is finished we have to get the list of people that the message was sent to. The easy answer would be &#8220;why not just do <strong>$TrackingLogsResults | select-object Recipients</strong> and pipe it along to something else?&#8221;</p>
<p>Well you can do that, but in some cases Recipients means actually a bunch of other addresses, and each recipient may appear multiple times in the entire list.</p>
<p>e.g. &#8211; this could be a list returned by the &#8220;easy&#8221; command</p>
<p style="padding-left: 30px;">{john@foo.com}</p>
<p style="padding-left: 30px;">{John@foo.com,Jane@foo.com}</p>
<p style="padding-left: 30px;">{Jill@foo.com,Josh@foo.com,Jake@foo.com}</p>
<p>Having duplicates is inefficient, everything will take longer in next steps. What I wanted was to have a list without duplicates, plus I get to show you some more &#8220;nice&#8221; scripting stuff <img src='http://www.rivnet.ro/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<h3>Compile Recipients List</h3>
<p>I spent quite some time figuring this out, so someone out there better find it useful <img src='http://www.rivnet.ro/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . The next step involved a &#8220;google shovel&#8221; to &#8220;dig up&#8221; how to break up those objects into one big list. Then the plan was to have a list that just had the unique email addresses &#8211; ideally. So here&#8217;s the &#8220;magic&#8221;:</p>
<pre class="brush: powershell; title: ; notranslate">$RecipientsExpanded = @()
$RecipientsExpanded = $TrackingLogResults | foreach-object {$RecipientsExpanded  = $RecipientsExpanded  + ($_.Recipients)}
$RecipientsGrouped = $RecipientsExpanded | group-object
$UniqueRecipients = $RecipientsGrouped | select-object Name | sort-object -property name</pre>
<ul>
<li>We created a blank <strong>array</strong> object that will host all recipients addresses  in &#8220;expanded form&#8221;.</li>
<li>For each result from the TrackingLog we added the <strong>array</strong> ($_.Recipients) to the $RecipientsExpanded array. At the end of this we have a single array with all the addresses, each an individual element in the array.</li>
<li>The <strong>Group-Object </strong>cmdlet is used to group all addresses by their name and in the end you <strong>have the list </strong>of  <strong>unique </strong>email addresses.</li>
</ul>
<h3>Actually remove offending messages</h3>
<p>Please see this <a href="http://msexchangeteam.com/archive/2007/04/13/437745.aspx" target="_blank">link</a> if you are planning to export the messages to PST. What is left to do is to take a page from the MSExchangeTeam blog and run get-mailbox| export-mailbox combo, only we are doing it on a reduced scale, only on the mailboxes that need it, that why I went through all the trouble of making that list!</p>
<pre class="brush: powershell; title: ; notranslate">$MailboxesList = $UniqueRecipients | foreach-object {
      $Filter = &quot;PrimarySmtpAddress -eq '&quot;+$_.Name+&quot;'&quot;
      get-mailbox -ignoredefaultscope -resultsize unlimited -Filter $Filter}</pre>
<p>The code above handles this task for forests with child  domains. I covered reasoning and use of -<em>Ignoredefaultscope </em>and -<em>Filter</em> in a previous <a href="http://www.rivnet.ro/2010/01/get-forwarding-email-address-of-forwarded-mailboxes.html" target="_blank">post</a>.</p>
<pre class="brush: powershell; title: ; notranslate">#get current admin UserPrincipalName
$Admin = [Security.Principal.WindowsIdentity]::GetCurrent().Name
#elevating the administrator's account to fulll access over all affected mailboxes
Add-MailboxPermission $MailboxesList -AccessRights FullAccess -User $Admin
export-Mailbox -Identity $MailboxesList –ContentKeywords &lt;enter part of message body&gt; -Recipients &lt;add recipients list&gt; –TargetMailbox admin_ –TargetFolder &quot;RecoveredEmails&quot; –DeleteContent</pre>
<ul>
<li>The final step grants the admin user full access over the  mailbox. The account being granted that right is <strong>$Admin</strong>, the account under which the script is running, it contains the UserPrincipalName of that account.</li>
<li>You also need to have admin rights on the &#8220;TargetMailbox&#8221; and the  &#8220;TargetFolder&#8221; should also exist beforehand.</li>
<li>We export the offending message(s) using <strong>Export-Mailbox</strong>.  Here it is important to be very careful and make the filtering as  strict as possible, since here you cannot remove a message based on the MessageID, so you could end up removing many more messages. Refer to the <a href="http://technet.microsoft.com/en-us/library/aa998579%28EXCHG.80%29.aspx" target="_blank">documentation </a>for export-mailbox, for all available switches for this purpose.</li>
</ul>
<p>After you run the last command get ready for some <strong>really long waiting</strong>, as it goes through all the mailboxes. Once it is finished, remove your permissions from those mailboxes.</p>
<pre>
<pre class="brush: powershell; title: ; notranslate">Remove-MailboxPermission $MailboxesList -AccessRights FullAccess -User $Admin</pre>
</pre>
<p>Phew this was a long post, but validating everything I explained here, took a while. The post is also packed with bits and pieces that can be your building block for other Exchange Shell scripts. I tried to show you how to take Exchange TrackingLog data and build a list of unique recipient addresses that you can use to filter out an unwanted message you tracked in the logs, and do that using export-mailbox commandlet. If you have any feedback/corrections/omissions please feel free to leave a comment.</p>
<p>Happy Scripting!</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.rivnet.ro%2F2010%2F02%2Fremoving-specific-messages-from-multiple-exchange-2007-mailboxes.html&amp;title=Removing%20specific%20message%28s%29%20from%20multiple%20Exchange%202007%20mailboxes" id="wpa2a_14"><img src="http://www.rivnet.ro/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.rivnet.ro/2010/02/removing-specific-messages-from-multiple-exchange-2007-mailboxes.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Get Forwarding Email Address of Forwarded Mailboxes</title>
		<link>http://www.rivnet.ro/2010/01/get-forwarding-email-address-of-forwarded-mailboxes.html</link>
		<comments>http://www.rivnet.ro/2010/01/get-forwarding-email-address-of-forwarded-mailboxes.html#comments</comments>
		<pubDate>Sat, 23 Jan 2010 13:00:38 +0000</pubDate>
		<dc:creator>Ionut Nica</dc:creator>
				<category><![CDATA[Management Shell]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Exchange Management Shell]]></category>
		<category><![CDATA[Exchange Migration]]></category>

		<guid isPermaLink="false">http://www.rivnet.ro/?p=60</guid>
		<description><![CDATA[ This second article, let's start by talking a little about the "-Filter" parameter, used in most Exch Shell cmd-lets that I've found myself abusing of these past days[...]It allows you to apply filters to the search on more Object Properties, much better than –Identity which we cannot use because of the -IgnoreDefaultScope[...]the second part of my post, the "get-recipient" cmdlet. Since there is no way for us to know to what object are the emails forwarded to [it could be a DL, a contact, a mailbox, another legacy user] we have to make our search as broad as possible. If you try to run get-mailbox on a contact object you will get nothing obviously.]]></description>
			<content:encoded><![CDATA[<p>This second article, let&#8217;s start by talking a little about the <strong>&#8220;-Filter</strong>&#8221; parameter, used in most Exch Shell cmd-lets that I&#8217;ve found myself abusing of these past days. I have supporting role in an Exchange 2007 Migration Project, and we were tasked with &#8220;cleaning up&#8221; what is left of the Legacy Exchange Servers in terms of mailboxes. The Domain structure contains multiple forests, one of which has quite a few child domains. In &#8220;everything is a possibility&#8221; domain structures say you may be required to</p>
<p style="padding-left: 60px;"><span style="font-size: small;"><strong><span style="text-decoration: underline;">Task #1 </span>- </strong>Get a list of all legacy      mailboxes that have forwarding addresses enabled or that DO NOT have a      forwarding address at all.</span></p>
<p style="padding-left: 60px;"><span style="font-size: small;"><strong>and then<br />
</strong></span></p>
<p style="padding-left: 60px;"><strong><span style="text-decoration: underline;">Task #2</span> &#8211; </strong>Based on the list from 1, create a report with forwarded email address and the forwarding address.</p>
<p style="padding-left: 30px;">
<h3><span style="font-size: medium;"><span style="text-decoration: underline;"><strong>Task #1</strong></span></span><strong> &#8211; </strong>Is done via this one liner</h3>
<pre class="brush: powershell; title: ; notranslate">$LegacyFWList = get-mailbox -ResultSize unlimited -RecipientTypeDetails LegacyMailbox -IgnoreDefaultScope -Filter {(ForwardingAddress -like '*')} | select-object ForwardingAddress,WindowsEmailAddress,RealFWAddress</pre>
<p>Code Breakdown:</p>
<pre class="brush: powershell; title: ; notranslate">get-mailbox -ResultSize unlimited -RecipientTypeDetails LegacyMailbox -IgnoreDefaultScope -Filter {(ForwardingAddress -like '*')} -ResultSize unlimited</pre>
<ul style="padding-left: 30px;">
<li>By default the cmdlet returns only the first 1000 results. I used <em>unlimited</em> but it also accepts a number as input</li>
</ul>
<ul style="padding-left: 30px;">
<li><em>get-mailbox </em>cmdlet extracts only &#8220;<em>LegacyMailbox</em>&#8221; objects  &#8211; this means mailboxes on servers pre Exchange 2007.</li>
</ul>
<ul style="padding-left: 30px;">
<li><em>IgnoreDefaultScope </em>performs a <strong>forest-wide search</strong>. Without this only legacy MBX&#8217;s on exchange servers in the forest root domain would have been returned.</li>
<li>Using this does have some limitations to it, check the help for what those are.</li>
<li>Biggest limitation is that -<em>Identity</em> must now be the a <strong>valid</strong> DN of the object.</li>
<li>I did not want to extract all DN’s in the forest and pipe them to the cmdlet, I looked for an alternative to this.</li>
</ul>
<p>I discovered the <strong><em>–Filter</em></strong> parameter. It allows you to apply filters to the search on more Object Properties, much better than <em>–Identity</em> which we cannot use because of the -<em>IgnoreDefaultScope</em>.</p>
<p>A great thing about it is that it can be used without any limitations with IgnoreDefaultScope. Full details about how to use –Filter Parameter and what properties of AD objects are filterable can be found <a href="http://technet.microsoft.com/en-us/library/bb124268%28EXCHG.80%29.aspx">here</a> and <a href="http://technet.microsoft.com/en-us/library/bb738155%28EXCHG.80%29.aspx">here</a>. Back to our task, you can see what we did.</p>
<pre style="padding-left: 30px;">-Filter {(ForwardingAddress -like '*')}</pre>
<p>We looked for any objects that contained any value in the &#8220;<em>ForwardingAddress</em>&#8221; Property of the returned object</p>
<ul style="padding-left: 30px;"></ul>
<p>But say you want the opposite of this &#8220;get all legacy mailboxes that have no forwarding address&#8221;&#8230;if would stand to reason that this should work:</p>
<pre>-Filter {(ForwardingAddress -notlike '*')}</pre>
<p>You are out of luck, it returns the entire list of legacy recipients. I went through a few filters until I found this:</p>
<ul style="padding-left: 30px;"></ul>
<pre>-Filter {(ForwardingAddress -ne $null)}</pre>
<p style="padding-left: 30px;">or</p>
<pre>-Filter {(ForwardingAddress -ne*')}</pre>
<p>I have to say that it was a surprise when I stumbled upon this, as it doesn&#8217;t really make sense. TechNet articles say -<em>like, </em>and I assume also -<em>notlike</em> accept wildcards, while -<em>eq</em> does not, you can also assume <em>-ne</em> does not. Well <em>-ne</em> does take wildcards, which I particularly do not mind in this case. I&#8217;m not sure if this is a bug, a feature, or just a flaw in my logic somehow and it&#8217;s working because it is supposed to.</p>
<p>Moving on&#8230;</p>
<ul style="padding-left: 30px;"></ul>
<pre class="brush: powershell; title: ; notranslate">select-object ForwardingAddress,WindowsEmailAddress,RealFWAddress</pre>
<ul style="padding-left: 30px;">
<li>I can save you running a &#8220;<em>| get-member</em>&#8221; on what the <em>get-mailbox</em> returned previously and tell you that only &#8220;<em>ForwardingAddress,WindowsEmailAddress</em>&#8221; are properties returned by <em>get-mailbox</em>.</li>
<li>&#8220;<em>RealFWAddress</em>&#8221; is something I made up. Why? Well unless you know already <em>ForwardingAddress</em> is not an address actually, it is a collection of properties for the recipient where emails are forwarded, the list contains DN, ObjectGUID, CN and others, not an actual email address.</li>
<li>RealFWAddress is a blank property, attached to the <em>$LegacyFWList</em> object, as a placeholder for when we do script a way to get that email address&#8230;which is now! read on</li>
</ul>
<p><span style="font-size: medium;"><strong>Task #2 &#8211; Create a list of  forwarded addresses and forwarding addresses</strong></span><strong><span style="font-size: medium;">.</span><br />
</strong></p>
<p>Now we come to the second part of my post, the &#8220;<strong><em>get-recipient</em>&#8221; </strong>cmdlet. Since there is no way for us to know to what object are the emails forwarded to [it could be a DL, a contact, a mailbox, another legacy user] we have to make our search as broad as possible. If you try to run get-mailbox on a contact object you will get nothing obviously.  We are using <em>foreach-object</em> to go through the entire list. <em>ForwardingAddress</em> is actually the CN of the object. We pass the DN of the Property to a cmdlet that will return a primary email address, if any.</p>
<p>This following code will accomplish just that:</p>
<pre class="brush: powershell; title: ; notranslate">
$LegacyFWList | foreach-object {
 $ForwardingDN = $_.ForwardingAddress.DistinguishedName
 $Filter = &quot;DistinguishedName -like '$ForwardingDN'&quot;
 $_.RealFWAddress = get-recipient -Filter $Filter -IgnoreDefaultScope | select-object PrimarySmtpAddress}
$LegacyFWList | export-csv &quot;c:\Change\This\Path.csv&quot;
</pre>
<p>Code Breakdown:</p>
<pre>$ForwardingDN = $_.ForwardingAddress.DistinguishedName
$Filter = "DistinguishedName -like '$ForwardingDN'"</pre>
<ul>
<li>I used these 2 variables in the code, $<em>DistinguishedName </em>and $<em>Filter</em>, trying to write a one liner resulted in somehow &#8220;deformed&#8221; filter  command that get-recipient would not understand.</li>
</ul>
<pre>$_.RealFWAddress = get-recipient -Filter $Filter -IgnoreDefaultScope | select-object PrimarySmtpAddress
</pre>
<ul>
<li>Lastly, <em>RealFWAddress</em> property I introduced above gets populated with <em>PrimarySmtpAddress</em> value.</li>
</ul>
<pre>$LegacyFWList | export-csv "c:\Change\This\Path.csv"</pre>
<ul>
<li>In the end all that&#8217;s left is export the $<em>LegacyFWList</em> variable to CSV and process however you wish, or just store it in xml / pass it on to another part of a script.</li>
</ul>
<p>I have to admit the last part of the code is less ideal. Why? Well, the export does not output a clean forwarding email address. I have tried various ways to fix it, but in the end I concluded that it took me 30 minutes of trying to get a nicer export, and 15 seconds to fix it after importing the csv in excel.</p>
<p>UPDATE 1: 26.01.2010 &#8211; added proper way to filter people with no forwarding address<br />
UPDATE 1: 21.02.2010 &#8211; added syntax highlighting and small rewrites</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rivnet.ro/2010/01/get-forwarding-email-address-of-forwarded-mailboxes.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Exchange 2007 Management Shell &#8211; Basics, Tips and Tricks</title>
		<link>http://www.rivnet.ro/2010/01/exchange-2007-management-shell-basics-tips-and-tricks.html</link>
		<comments>http://www.rivnet.ro/2010/01/exchange-2007-management-shell-basics-tips-and-tricks.html#comments</comments>
		<pubDate>Mon, 11 Jan 2010 21:07:02 +0000</pubDate>
		<dc:creator>Ionut Nica</dc:creator>
				<category><![CDATA[Management Shell]]></category>
		<category><![CDATA[NT Batch]]></category>
		<category><![CDATA[Powershell]]></category>
		<category><![CDATA[Exchange]]></category>
		<category><![CDATA[get-help]]></category>

		<guid isPermaLink="false">http://rivnet.ro/?p=27</guid>
		<description><![CDATA[This first post i&#8217;d like to talk a little about Exchange 2007&#8242;s Management Shell. If you are already working with Exchange 2007, you must know by now that there has been a shift in how administration and management tasks are done. Microsoft introduced the Management Shell of Exchange as a Powershell Extension, and a lot [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;">This first post i&#8217;d like to talk a little about Exchange 2007&#8242;s <strong>Management Shell. </strong>If you are already working with Exchange 2007,  you must know by now that there has been a shift in how administration and management tasks are done. Microsoft introduced the Management Shell of Exchange as a Powershell Extension, and a lot of the GUI tasks are now done from the command line.</p>
<p style="text-align: left;"><strong>Powershell </strong>is Microsoft&#8217;s new (or maybe not so new,  let&#8217;s just say latest , it has been with use for some years) extensible command shell interface. It is built on .NET Framework, so it may look more like a shell aimed at the programming savvy, but I think people that have really basic programming skills can handle it after some getting used to.</p>
<p style="text-align: left;">How to get it? Well assuming you have an Exchange 2007 server in your organization, you have it by default on the Exchange Servers. You can and should use the shell on the Exchange Servers [running scripts closest to the "managed entities" is always best IMO, you avoid adding additional Points of Failure] but you can also download the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=6be38633-7248-4532-929b-76e9c677e802&amp;displaylang=en" target="_blank">Exchange Management Tools for Exchange 2007</a> and install them on your own workstation, or a workstation you designate for management.</p>
<p style="text-align: left;">Ok, so now you have the tools installed. Unless you already found the link to the <strong>Exchange Management Shell</strong> on your start menu, you can start the tools by typing this in the run box.</p>
<pre style="text-align: left;">%windir%\system32\windowspowershell\v1.0\powershell.exe -PSConsoleFile "%ProgramFiles%\Microsoft\Exchange Server\bin\exshell.psc1" -noexit -command ". '%ProgramFiles%\Microsoft\Exchange Server\bin\Exchange.ps1'"
</pre>
<p>You can probably use this in some scripted NT batch files, if you like. You will find some good information on Google about introductions to powershell, I won&#8217;t bore you with them. I&#8217;m going to assume you have the shell, have done some really light reading on the topic.</p>
<p>Here are some quick fixes for <strong>Powershell&#8217;s quirks</strong> though. You must have stumbled upon this at least once.</p>
<p>Ever ran an extended help command like the one below?</p>
<pre style="padding-left: 30px;">get-help Get-MailBox -full
</pre>
<p>Lots of lines scrolling, you couldn&#8217;t read a thing. It&#8217;s like one of those days you wish you were either in The Matrix or Startrek, so you can read the damn command-let help slowly or be an Android&#8230;or you could have not skipped the RTFM part of powershell, but if you&#8217;re like me, you did.</p>
<p>Worst part about this is that the powershell.exe line buffer is the same as the buffer of cmd.exe, so if the help is big enough, scrolling back up won&#8217;t give you a change to read all of the help.</p>
<p style="padding-left: 30px;">
<p style="padding-left: 30px;">
<p style="padding-left: 30px;">
<p style="padding-left: 30px;">
<p><strong>How to Fix it? &#8211; </strong>Not to worry old<em> NT batch</em> and <em>Powershell</em> have the answer</p>
<p style="padding-left: 30px;">
<p style="padding-left: 30px;"><strong>Tip #1 &#8211; </strong><em>Using Powershell </em>- For this I should have done the obvious, meaning taking a closer look at the output of:</p>
<pre style="padding-left: 90px;">get-help get-help (yes you can get-help on get-help)
</pre>
<p style="padding-left: 60px;">There&#8217;s a little line that says there&#8217;s also the option of running, <strong>help </strong>[command] instead of<em> get-help</em>. You you try:</p>
<pre style="padding-left: 90px;">help get-mailbox -full
</pre>
<p style="padding-left: 60px;">You get the equivalent of the <strong>/p</strong> switch on the NT batch, now that&#8217;s help for non Android people <img src='http://www.rivnet.ro/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p style="padding-left: 90px;">
<p style="padding-left: 30px;"><strong>Tip #2</strong> &#8211; <em>Oldschool</em>, using NT batch you can redirect the output of help to a text file and read it at your leisure.</p>
<pre style="padding-left: 90px;">get-help Get-mailbox-full &gt; c:\get-mailbox.help
notepad C:\get-mailbox.help
</pre>
<p><strong>Which one is better?</strong></p>
<p><em>Powershell </em>method is <em>quicker </em>because you don&#8217;t have to notepad the text file and search for it there. However you cannot use the same method for cmd-let output [or may I have not figured out how, yet], basically reading the output of a cmd-let page by page.</p>
<p>For that you still have to do use the <em>general </em>method, <em>in NT Batch</em> redirect the output to a file and read that later on, like this for example:</p>
<pre style="padding-left: 30px;">get-excommand | select-object Type,Name | ft &gt; c:\ex-command.help</pre>
<pre style="padding-left: 30px;">notepad C:\ex-command.help
</pre>
<p>This should help anyone struggling with learning the Exchange shell syntax for referencing all of the cmd-let switches available.</p>
<p>Happy Scripting, hope this first post was not so bad.</p>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 120px; width: 1px; height: 1px;">http://www.microsoft.com/downloads/details.aspx?familyid=1DC0F61B-D30F-44A2-882E-12DDD4EE09D2&amp;displaylang=e</div>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.rivnet.ro%2F2010%2F01%2Fexchange-2007-management-shell-basics-tips-and-tricks.html&amp;title=Exchange%202007%20Management%20Shell%20%26%238211%3B%20Basics%2C%20Tips%20and%20Tricks" id="wpa2a_16"><img src="http://www.rivnet.ro/wp-content/plugins/add-to-any/share_save_171_16.png" width="171" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.rivnet.ro/2010/01/exchange-2007-management-shell-basics-tips-and-tricks.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

