<?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>Use PowerShell &#187; .NET Framework</title>
	<atom:link href="http://blog.usepowershell.com/category/net-framework/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.usepowershell.com</link>
	<description>Real Admins Script</description>
	<lastBuildDate>Sat, 17 Jul 2010 14:38:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Using the Sync Framework from PowerShell</title>
		<link>http://blog.usepowershell.com/2009/11/using-the-sync-framework-from-powershell/</link>
		<comments>http://blog.usepowershell.com/2009/11/using-the-sync-framework-from-powershell/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 14:11:50 +0000</pubDate>
		<dc:creator>Steven Murawski</dc:creator>
				<category><![CDATA[.NET Framework]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[PowerShell Version 2]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[Sync Framework]]></category>

		<guid isPermaLink="false">http://blog.usepowershell.com/2009/11/using-the-sync-framework-from-powershell/</guid>
		<description><![CDATA[I’ve been exploring the Sync Framework for use in a couple of projects I have going and PowerShell is my preferred exploratory environment. It was a bit of fun, since I got to work with eventing for the first time in V2. First, I downloaded the Sync Framework Software Development Kit.  That provided me with [...]]]></description>
			<content:encoded><![CDATA[<p>I’ve been exploring the <a href="http://msdn.microsoft.com/en-us/sync/default.aspx" target="_blank">Sync Framework</a> for use in a couple of projects I have going and <a href="http://msdn.microsoft.com/en-us/library/ms714418(VS.85).aspx" target="_blank">PowerShell</a> is my preferred exploratory environment.</p>
<p>It was a bit of fun, since I got to work with eventing for the first time in V2.</p>
<p>First, I downloaded the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=89adbb1e-53ff-41b5-ba17-8e43a2e66254&amp;displaylang=en" target="_blank">Sync Framework Software Development Kit</a>.  That provided me with the Sync Framework runtime as well as some documentation.</p>
<p>The easiest way for me to get started was to take one <a href="http://msdn.microsoft.com/en-us/library/ee617386(SQL.105).aspx" target="_blank">of the samples</a> and convert that to PowerShell.</p>
<p>I’m going to walk along the MSDN Sample and provide the equivalent PowerShell, as well as any changes I made to make it feel more PowerShell-y.</p>
<h3>Setting Synchronization Options</h3>
<p>We are working with the File Sync Provider First up is setting the <a href="http://msdn.microsoft.com/en-us/library/microsoft.synchronization.files.filesyncoptions(SQL.105).aspx" target="_blank">FileSyncOptions</a>.  FileSyncOptions are an enumeration (a limited list defined in code that maps to certain values) whose values are controlled by setting the appropriate bits to indicate the presence or absence of a flag.  <a href="http://twitter.com/meson3902" target="_blank">Mark Schill</a> has <a href="http://www.cmschill.net/stringtheory/2009/05/02/bitwise-operators/" target="_blank">a great post about how to set bitwise operations</a>.</p>
<pre class="PowerShellColorizedScript"><span style="color: #ff4500">$options </span><span style="color: #a9a9a9">= </span><span style="color: #008080">[Microsoft.Synchronization.Files.FileSyncOptions]</span><span style="color: #a9a9a9">::</span><span style="color: #000000">ExplicitDetectChanges</span>
<span style="color: #ff4500">$options</span> <span style="color: #a9a9a9">=</span> <span style="color: #ff4500">$options</span> <span style="color: #a9a9a9">-bor</span> <span style="color: #008080">[Microsoft.Synchronization.Files.FileSyncOptions]</span><span style="color: #a9a9a9">::</span><span style="color: #000000">RecycleDeletedFiles</span>
<span style="color: #ff4500">$options</span> <span style="color: #a9a9a9">=</span> <span style="color: #ff4500">$options</span> <span style="color: #a9a9a9">-bor</span> <span style="color: #008080">[Microsoft.Synchronization.Files.FileSyncOptions]</span><span style="color: #a9a9a9">::</span><span style="color: #000000">RecyclePreviousFileOnUpdates</span>
<span style="color: #ff4500">$options</span> <span style="color: #a9a9a9">=</span> <span style="color: #ff4500">$options</span> <span style="color: #a9a9a9">-bor</span> <span style="color: #008080">[Microsoft.Synchronization.Files.FileSyncOptions]</span><span style="color: #a9a9a9">::</span><span style="color: #000000">RecycleConflictLoserFiles</span></pre>
<h3>Specifying a Static Filter</h3>
<p>With the <a href="http://msdn.microsoft.com/en-us/library/bb902860(SQL.105).aspx" target="_blank">File System provider,</a> we can provide filters to include or exclude files and directories.</p>
<p>$FileNameFilter and $SubdirectoryNameFilter are parameters that take strings or string arrays.</p>
<pre class="PowerShellColorizedScript"><span style="color: #ff4500">$filter</span> <span style="color: #a9a9a9">=</span> <span style="color: #0000ff">New-Object</span> <span style="color: #8a2be2">Microsoft.Synchronization.Files.FileSyncScopeFilter</span>
<span style="color: #00008b">if</span> <span style="color: #000000">(</span><span style="color: #ff4500">$FileNameFilter</span><span style="color: #a9a9a9">.</span><span style="color: #000000">count</span> <span style="color: #a9a9a9">-gt</span> <span style="color: #800080">0</span><span style="color: #000000">)</span>
<span style="color: #000000">{</span>
   <span style="color: #ff4500">$FileNameFilter</span> <span style="color: #a9a9a9">|</span> <span style="color: #0000ff">ForEach-Object</span> <span style="color: #000000">{</span> <span style="color: #ff4500">$filter</span><span style="color: #a9a9a9">.</span><span style="color: #000000">FileNameExcludes</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Add</span><span style="color: #000000">(</span><span style="color: #ff4500">$_</span><span style="color: #000000">)</span> <span style="color: #000000">}</span>
<span style="color: #000000">}</span>
<span style="color: #00008b">if</span> <span style="color: #000000">(</span><span style="color: #ff4500">$SubdirectoryNameFilter</span><span style="color: #a9a9a9">.</span><span style="color: #000000">count</span> <span style="color: #a9a9a9">-gt</span> <span style="color: #800080">0</span><span style="color: #000000">)</span>
<span style="color: #000000">{</span>
   <span style="color: #ff4500">$SubdirectoryNameFilter</span> <span style="color: #a9a9a9">|</span> <span style="color: #0000ff">ForEach-Object</span> <span style="color: #000000">{</span> <span style="color: #ff4500">$filter</span><span style="color: #a9a9a9">.</span><span style="color: #000000">SubdirectoryExcludes</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Add</span><span style="color: #000000">(</span><span style="color: #ff4500">$_</span><span style="color: #000000">)</span> <span style="color: #000000">}</span>
<span style="color: #000000">}</span></pre>
<h3>Performing Change Detection</h3>
<p>After configuring the filter, we examine the folders and files located at the paths specified.  If there has not been any previous synchronization, a metadata file will be created in each location to track any changes, updates, and deletes for later synchronization.</p>
<pre class="PowerShellColorizedScript"><span style="color: #00008b">function</span> <span style="color: #8a2be2">Get-FileSystemChange</span><span style="color: #000000">(</span><span style="color: #000000">)</span>
<span style="color: #000000">{</span>
    <span style="color: #00008b">param</span> <span style="color: #000000">(</span><span style="color: #ff4500">$path</span><span style="color: #a9a9a9">,</span> <span style="color: #ff4500">$filter</span><span style="color: #a9a9a9">,</span> <span style="color: #ff4500">$options</span><span style="color: #000000">)</span>
    <span style="color: #00008b">try</span>
    <span style="color: #000000">{</span>
        <span style="color: #ff4500">$provider</span> <span style="color: #a9a9a9">=</span> <span style="color: #0000ff">new-object</span> <span style="color: #8a2be2">Microsoft.Synchronization.Files.FileSyncProvider</span> <span style="color: #000080">-ArgumentList</span> <span style="color: #ff4500">$path</span><span style="color: #a9a9a9">,</span> <span style="color: #ff4500">$filter</span><span style="color: #a9a9a9">,</span> <span style="color: #ff4500">$options</span>
        <span style="color: #ff4500">$provider</span><span style="color: #a9a9a9">.</span><span style="color: #000000">DetectChanges</span><span style="color: #000000">(</span><span style="color: #000000">)</span>
    <span style="color: #000000">}</span>
    <span style="color: #00008b">finally</span>
    <span style="color: #000000">{</span>
        <span style="color: #00008b">if</span> <span style="color: #000000">(</span><span style="color: #ff4500">$provider</span> <span style="color: #a9a9a9">-ne</span> <span style="color: #ff4500">$null</span><span style="color: #000000">)</span>
        <span style="color: #000000">{</span>
            <span style="color: #ff4500">$provider</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Dispose</span><span style="color: #000000">(</span><span style="color: #000000">)</span>
        <span style="color: #000000">}</span>
    <span style="color: #000000">}</span>
<span style="color: #000000">}</span></pre>
<p> </p>
<pre class="PowerShellColorizedScript"><span style="color: #0000ff">Get-FileSystemChange</span> <span style="color: #ff4500">$SourcePath</span> <span style="color: #ff4500">$filter</span> <span style="color: #ff4500">$options</span>
<span style="color: #0000ff">Get-FileSystemChange</span> <span style="color: #ff4500">$DestinationPath</span> <span style="color: #ff4500">$filter</span> <span style="color: #ff4500">$options</span></pre>
<p> </p>
<h3>Handling Conflicts</h3>
<p>Conflict resolution in the Sync Framework happens at the at the event level.  An event is merely something that happens that can trigger other actions.  Using <a href="http://technet.microsoft.com/en-us/library/dd347672.aspx" target="_blank">Register-ObjectEvent</a>, we can associate one or more scriptblocks with an event.</p>
<p>First, I defined scriptblocks to handle the conflicts.  There is an enumeration, the <a href="http://msdn.microsoft.com/en-us/library/microsoft.synchronization.conflictresolutionaction(SQL.105).aspx" target="_blank">ConflictResolutionAction</a> enumeration, that provides some options for dealing with conflicts.  For this example, we are going to pick the source object as the winner for any conflicts.</p>
<p>You will also notice another type of conflict defined, and that is a Constraint conflict.  That can occur when an object of the same name is added on both sides in between synchronizations.  The resolution options for these conflicts can be found in the <a href="http://msdn.microsoft.com/en-us/library/microsoft.synchronization.constraintconflictresolutionaction(SQL.105).aspx" target="_blank">ConstraintConflictResolutionAction</a> enumeration.</p>
<pre class="PowerShellColorizedScript"><span style="color: #ff4500">$ItemConflictAction</span> <span style="color: #a9a9a9">=</span>   <span style="color: #000000">{</span>
    <span style="color: #ff4500">$event</span><span style="color: #a9a9a9">.</span><span style="color: #000000">SourceEventArgs</span><span style="color: #a9a9a9">.</span><span style="color: #000000">SetResolutionAction</span><span style="color: #000000">(</span><span style="color: #008080">[Microsoft.Synchronization.ConflictResolutionAction]</span><span style="color: #a9a9a9">::</span><span style="color: #000000">SourceWins</span><span style="color: #000000">)</span>
    <span style="color: #008080">[string[]]</span><span style="color: #ff4500">$global:FileSyncReport</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Conflicted</span> <span style="color: #a9a9a9">+=</span> <span style="color: #ff4500">$event</span><span style="color: #a9a9a9">.</span><span style="color: #000000">SourceEventArgs</span><span style="color: #a9a9a9">.</span><span style="color: #000000">DestinationChange</span><span style="color: #a9a9a9">.</span><span style="color: #000000">ItemId</span>
<span style="color: #000000">}</span>
<span style="color: #ff4500">$ItemConstraintAction</span> <span style="color: #a9a9a9">=</span> <span style="color: #000000">{</span>
     <span style="color: #ff4500">$event</span><span style="color: #a9a9a9">.</span><span style="color: #000000">SourceEventArgs</span><span style="color: #a9a9a9">.</span><span style="color: #000000">SetResolutionAction</span><span style="color: #000000">(</span><span style="color: #008080">[Microsoft.Synchronization.ConstraintConflictResolutionAction]</span><span style="color: #a9a9a9">::</span><span style="color: #000000">SourceWins</span><span style="color: #000000">)</span>
     <span style="color: #008080">[string[]]</span><span style="color: #ff4500">$global:FileSyncReport</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Constrained</span> <span style="color: #a9a9a9">+=</span> <span style="color: #ff4500">$event</span><span style="color: #a9a9a9">.</span><span style="color: #000000">SourceEventArgs</span><span style="color: #a9a9a9">.</span><span style="color: #000000">DestinationChange</span><span style="color: #a9a9a9">.</span><span style="color: #000000">ItemId</span>
<span style="color: #000000">}</span>            

<span style="color: #006400"># Configure the events for conflicts or constraints for the source and destination providers</span>
<span style="color: #ff4500">$destinationCallbacks</span> <span style="color: #a9a9a9">=</span> <span style="color: #ff4500">$destinationProvider</span><span style="color: #a9a9a9">.</span><span style="color: #000000">DestinationCallbacks</span>
<span style="color: #0000ff">Register-ObjectEvent</span> <span style="color: #000080">-InputObject</span> <span style="color: #ff4500">$destinationCallbacks</span> <span style="color: #000080">-EventName</span> <span style="color: #8a2be2">ItemConflicting</span> <span style="color: #000080">-Action</span> <span style="color: #ff4500">$ItemConflictAction</span> <span style="color: #a9a9a9">|</span> <span style="color: #0000ff">Out-Null</span>
<span style="color: #0000ff">Register-ObjectEvent</span> <span style="color: #000080">-InputObject</span> <span style="color: #ff4500">$destinationCallbacks</span> <span style="color: #000080">-EventName</span> <span style="color: #8a2be2">ItemConstraint</span> <span style="color: #000080">-Action</span> <span style="color: #ff4500">$ItemConstraintAction</span> <span style="color: #a9a9a9">|</span> <span style="color: #0000ff">Out-Null</span>            

<span style="color: #ff4500">$sourceCallbacks</span> <span style="color: #a9a9a9">=</span> <span style="color: #ff4500">$SourceProvider</span><span style="color: #a9a9a9">.</span><span style="color: #000000">DestinationCallbacks</span>
<span style="color: #0000ff">Register-ObjectEvent</span> <span style="color: #000080">-InputObject</span> <span style="color: #ff4500">$sourceCallbacks</span> <span style="color: #000080">-EventName</span> <span style="color: #8a2be2">ItemConflicting</span> <span style="color: #000080">-Action</span> <span style="color: #ff4500">$ItemConflictAction</span> <span style="color: #a9a9a9">|</span> <span style="color: #0000ff">Out-Null</span>
<span style="color: #0000ff">Register-ObjectEvent</span> <span style="color: #000080">-InputObject</span> <span style="color: #ff4500">$sourceCallbacks</span> <span style="color: #000080">-EventName</span> <span style="color: #8a2be2">ItemConstraint</span> <span style="color: #000080">-Action</span> <span style="color: #ff4500">$ItemConstraintAction</span> <span style="color: #a9a9a9">|</span> <span style="color: #0000ff">Out-Null</span></pre>
<p>We also see for the first time in the script blocks a variable called $event.  This is an automatic variable exposed by the event and provides us information that we can use in our action.</p>
<p>Finally, I’m updating a variable in the global scope.  There probably is a better way to handle this, but scriptblocks executed in response to events only have access to the global scope and any of the automatic variable exposed to it.  Therefore, I use a variable in the global scope to gather my reporting information.</p>
<h3>Synchronizing Two Replicas</h3>
<p>To start to synchronize the two sides, first we set up the synchronization via a <a href="http://msdn.microsoft.com/en-us/library/microsoft.synchronization.syncorchestrator.aspx" target="_blank">SyncOrchestrator</a> and assign it the local and remote providers, as well as defining the direction of the synchronization.  In this example (sticking with the format from MSDN, we will do an Upload, which is in the <a href="http://msdn.microsoft.com/en-us/library/microsoft.synchronization.syncdirectionorder.aspx" target="_blank">SyncDirectionOrder enumeration</a> (other options are Download, DownloadAndUpload, and UploadAndDownload). </p>
<pre class="PowerShellColorizedScript"><span style="color: #006400"># Create the agent that will perform the file sync</span>
<span style="color: #ff4500">$agent</span> <span style="color: #a9a9a9">=</span> <span style="color: #0000ff">New-Object</span>  <span style="color: #8a2be2">Microsoft.Synchronization.SyncOrchestrator</span>
<span style="color: #ff4500">$agent</span><span style="color: #a9a9a9">.</span><span style="color: #000000">LocalProvider</span> <span style="color: #a9a9a9">=</span> <span style="color: #ff4500">$sourceProvider</span>
<span style="color: #ff4500">$agent</span><span style="color: #a9a9a9">.</span><span style="color: #000000">RemoteProvider</span> <span style="color: #a9a9a9">=</span> <span style="color: #ff4500">$destinationProvider</span>            

<span style="color: #006400"># Upload changes from the source to the destination.</span>
<span style="color: #ff4500">$agent</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Direction</span> <span style="color: #a9a9a9">=</span> <span style="color: #008080">[Microsoft.Synchronization.SyncDirectionOrder]</span><span style="color: #a9a9a9">::</span><span style="color: #000000">Upload</span>            

<span style="color: #0000ff">Write-Host</span> <span style="color: #8b0000">"Synchronizing changes from $($sourceProvider.RootDirectoryPath) to replica: $($destinationProvider.RootDirectoryPath)"</span>
<span style="color: #ff4500">$agent</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Synchronize</span><span style="color: #000000">(</span><span style="color: #000000">)</span><span style="color: #000000">;</span></pre>
<p>To achieve two way synchronization, we will do the upload twice, reversing the order of the providers.</p>
<pre class="PowerShellColorizedScript"><span style="color: #0000ff">Invoke-OneWayFileSync</span> <span style="color: #000080">-SourcePath</span> <span style="color: #ff4500">$SourcePath</span> <span style="color: #000080">-DestinationPath</span> <span style="color: #ff4500">$DestinationPath</span> <span style="color: #000080">-Filter</span> <span style="color: #ff4500">$null</span> <span style="color: #000080">-Options</span> <span style="color: #ff4500">$options</span>
<span style="color: #0000ff">Invoke-OneWayFileSync</span> <span style="color: #000080">-SourcePath</span> <span style="color: #ff4500">$DestinationPath</span> <span style="color: #000080">-DestinationPath</span> <span style="color: #ff4500">$SourcePath</span> <span style="color: #000080">-Filter</span> <span style="color: #ff4500">$null</span> <span style="color: #000080">-Options</span> <span style="color: #ff4500">$options</span></pre>
<h3>Full Example</h3>
<p>I modified the example to write out a custom object (and the logging is in the variable in the global scope as noted in the Handling Conflicts section) with the results of the synchronization (rather than logging it to the console).</p>
<p>In all, my translation is pretty similar to the example code, but there are some differences. </p>
<pre class="PowerShellColorizedScript"><span style="color: #006400"># Requires -Version 2</span>
<span style="color: #006400"># Also depends on having the Microsoft Sync Framework 2.0 SDK or Runtime</span>
<span style="color: #006400"># --SDK--</span>
<span style="color: #006400"># http://www.microsoft.com/downloads/details.aspx?FamilyID=89adbb1e-53ff-41b5-ba17-8e43a2e66254&amp;displaylang=en</span>
<span style="color: #006400"># --Runtime--</span>
<span style="color: #006400"># http://www.microsoft.com/downloads/details.aspx?FamilyId=109DB36E-CDD0-4514-9FB5-B77D9CEA37F6&amp;displaylang=en</span>
<span style="color: #006400">#</span>
<span style="color: #006400">#</span>            

<span style="color: #a9a9a9">[</span><span style="color: #add8e6">CmdletBinding</span><span style="color: #000000">(</span><span style="color: #000000">SupportsShouldProcess</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$true</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span>
<span style="color: #00008b">param</span> <span style="color: #000000">(</span>
    <span style="color: #a9a9a9">[</span><span style="color: #add8e6">Parameter</span><span style="color: #000000">(</span><span style="color: #000000">Position</span><span style="color: #a9a9a9">=</span><span style="color: #800080">1</span><span style="color: #a9a9a9">,</span> <span style="color: #000000">Mandatory</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$true</span><span style="color: #a9a9a9">,</span> <span style="color: #000000">ValueFromPipelineByPropertyName</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$true</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span>
    <span style="color: #a9a9a9">[</span><span style="color: #add8e6">Alias</span><span style="color: #000000">(</span><span style="color: #8b0000">'FullName'</span><span style="color: #a9a9a9">,</span> <span style="color: #8b0000">'Path'</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span>
    <span style="color: #008080">[string]</span><span style="color: #ff4500">$SourcePath</span>
    <span style="color: #a9a9a9">,</span> <span style="color: #a9a9a9">[</span><span style="color: #add8e6">Parameter</span><span style="color: #000000">(</span><span style="color: #000000">Position</span><span style="color: #a9a9a9">=</span><span style="color: #800080">2</span><span style="color: #a9a9a9">,</span> <span style="color: #000000">Mandatory</span><span style="color: #a9a9a9">=</span><span style="color: #ff4500">$true</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span>
    <span style="color: #008080">[string]</span><span style="color: #ff4500">$DestinationPath</span>
    <span style="color: #a9a9a9">,</span> <span style="color: #a9a9a9">[</span><span style="color: #add8e6">Parameter</span><span style="color: #000000">(</span><span style="color: #000000">Position</span><span style="color: #a9a9a9">=</span><span style="color: #800080">3</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span>
    <span style="color: #008080">[string[]]</span><span style="color: #ff4500">$FileNameFilter</span>
    <span style="color: #a9a9a9">,</span> <span style="color: #a9a9a9">[</span><span style="color: #add8e6">Parameter</span><span style="color: #000000">(</span><span style="color: #000000">Position</span><span style="color: #a9a9a9">=</span><span style="color: #800080">4</span><span style="color: #000000">)</span><span style="color: #a9a9a9">]</span>
    <span style="color: #008080">[string[]]</span><span style="color: #ff4500">$SubdirectoryNameFilter</span>
<span style="color: #000000">)</span>
<span style="color: #006400">&lt;#
    .Synopsis
        Synchronizes to directory trees
    .Description
        Examines two directory structures (SourcePath and DestinationPath) and uses the Microsoft Sync Framework
        File System Provider to synchronize them.
    .Example
        An example of using the command
#&gt;</span>
<span style="color: #00008b">begin</span>
<span style="color: #000000">{</span>
    <span style="color: #008080">[reflection.assembly]</span><span style="color: #a9a9a9">::</span><span style="color: #000000">LoadWithPartialName</span><span style="color: #000000">(</span><span style="color: #8b0000">'Microsoft.Synchronization'</span><span style="color: #000000">)</span> <span style="color: #a9a9a9">|</span> <span style="color: #0000ff">Out-Null</span>
    <span style="color: #008080">[reflection.assembly]</span><span style="color: #a9a9a9">::</span><span style="color: #000000">LoadWithPartialName</span><span style="color: #000000">(</span><span style="color: #8b0000">'Microsoft.Synchronization.Files'</span><span style="color: #000000">)</span> <span style="color: #a9a9a9">|</span> <span style="color: #0000ff">Out-Null</span>            

    <span style="color: #00008b">function</span> <span style="color: #8a2be2">Get-FileSystemChange</span><span style="color: #000000">(</span><span style="color: #000000">)</span>
    <span style="color: #000000">{</span>
        <span style="color: #00008b">param</span> <span style="color: #000000">(</span><span style="color: #ff4500">$path</span><span style="color: #a9a9a9">,</span> <span style="color: #ff4500">$filter</span><span style="color: #a9a9a9">,</span> <span style="color: #ff4500">$options</span><span style="color: #000000">)</span>
        <span style="color: #00008b">try</span>
        <span style="color: #000000">{</span>
            <span style="color: #ff4500">$provider</span> <span style="color: #a9a9a9">=</span> <span style="color: #0000ff">new-object</span> <span style="color: #8a2be2">Microsoft.Synchronization.Files.FileSyncProvider</span> <span style="color: #000080">-ArgumentList</span> <span style="color: #ff4500">$path</span><span style="color: #a9a9a9">,</span> <span style="color: #ff4500">$filter</span><span style="color: #a9a9a9">,</span> <span style="color: #ff4500">$options</span>
            <span style="color: #ff4500">$provider</span><span style="color: #a9a9a9">.</span><span style="color: #000000">DetectChanges</span><span style="color: #000000">(</span><span style="color: #000000">)</span>
        <span style="color: #000000">}</span>
        <span style="color: #00008b">finally</span>
        <span style="color: #000000">{</span>
            <span style="color: #00008b">if</span> <span style="color: #000000">(</span><span style="color: #ff4500">$provider</span> <span style="color: #a9a9a9">-ne</span> <span style="color: #ff4500">$null</span><span style="color: #000000">)</span>
            <span style="color: #000000">{</span>
                <span style="color: #ff4500">$provider</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Dispose</span><span style="color: #000000">(</span><span style="color: #000000">)</span>
            <span style="color: #000000">}</span>
        <span style="color: #000000">}</span>
    <span style="color: #000000">}</span>            

    <span style="color: #00008b">function</span> <span style="color: #8a2be2">Invoke-OneWayFileSync</span><span style="color: #000000">(</span><span style="color: #000000">)</span>
    <span style="color: #000000">{</span>
        <span style="color: #00008b">param</span> <span style="color: #000000">(</span><span style="color: #ff4500">$SourcePath</span><span style="color: #a9a9a9">,</span> <span style="color: #ff4500">$DestinationPath</span><span style="color: #a9a9a9">,</span>
                    <span style="color: #ff4500">$Filter</span><span style="color: #a9a9a9">,</span> <span style="color: #ff4500">$Options</span><span style="color: #000000">)</span>
        <span style="color: #ff4500">$ApplyChangeJobs</span> <span style="color: #a9a9a9">=</span> <span style="color: #000000">@(</span><span style="color: #000000">)</span>
        <span style="color: #ff4500">$AppliedChangeJobs</span> <span style="color: #a9a9a9">=</span> <span style="color: #000000">@(</span><span style="color: #000000">)</span>
        <span style="color: #00008b">try</span>
        <span style="color: #000000">{</span>
            <span style="color: #006400"># Scriptblocks to handle the events raised during synchronization</span>
            <span style="color: #ff4500">$AppliedChangeAction</span> <span style="color: #a9a9a9">=</span> <span style="color: #000000">{</span>
                <span style="color: #ff4500">$argument</span> <span style="color: #a9a9a9">=</span> <span style="color: #ff4500">$event</span><span style="color: #a9a9a9">.</span><span style="color: #000000">SourceEventArgs</span>
                <span style="color: #00008b">switch</span> <span style="color: #000000">(</span><span style="color: #ff4500">$argument</span><span style="color: #a9a9a9">.</span><span style="color: #000000">ChangeType</span><span style="color: #000000">)</span>
                <span style="color: #000000">{</span>
                    <span style="color: #000000">{</span> <span style="color: #ff4500">$argument</span><span style="color: #a9a9a9">.</span><span style="color: #000000">ChangeType</span> <span style="color: #a9a9a9">-eq</span> <span style="color: #008080">[Microsoft.Synchronization.Files.ChangeType]</span><span style="color: #a9a9a9">::</span><span style="color: #000000">Create</span> <span style="color: #000000">}</span> <span style="color: #000000">{</span><span style="color: #008080">[string[]]</span><span style="color: #ff4500">$global:FileSyncReport</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Created</span> <span style="color: #a9a9a9">+=</span> <span style="color: #ff4500">$argument</span><span style="color: #a9a9a9">.</span><span style="color: #000000">NewFilePath</span><span style="color: #000000">}</span>
                    <span style="color: #000000">{</span> <span style="color: #ff4500">$argument</span><span style="color: #a9a9a9">.</span><span style="color: #000000">ChangeType</span> <span style="color: #a9a9a9">-eq</span> <span style="color: #008080">[Microsoft.Synchronization.Files.ChangeType]</span><span style="color: #a9a9a9">::</span><span style="color: #000000">Delete</span> <span style="color: #000000">}</span> <span style="color: #000000">{</span><span style="color: #008080">[string[]]</span><span style="color: #ff4500">$global:FileSyncReport</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Deleted</span> <span style="color: #a9a9a9">+=</span> <span style="color: #ff4500">$argument</span><span style="color: #a9a9a9">.</span><span style="color: #000000">OldFilePath</span><span style="color: #000000">}</span>
                    <span style="color: #000000">{</span> <span style="color: #ff4500">$argument</span><span style="color: #a9a9a9">.</span><span style="color: #000000">ChangeType</span> <span style="color: #a9a9a9">-eq</span> <span style="color: #008080">[Microsoft.Synchronization.Files.ChangeType]</span><span style="color: #a9a9a9">::</span><span style="color: #000000">Update</span> <span style="color: #000000">}</span> <span style="color: #000000">{</span><span style="color: #008080">[string[]]</span><span style="color: #ff4500">$global:FileSyncReport</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Updated</span> <span style="color: #a9a9a9">+=</span> <span style="color: #ff4500">$argument</span><span style="color: #a9a9a9">.</span><span style="color: #000000">OldFilePath</span><span style="color: #000000">}</span>
                    <span style="color: #000000">{</span> <span style="color: #ff4500">$argument</span><span style="color: #a9a9a9">.</span><span style="color: #000000">ChangeType</span> <span style="color: #a9a9a9">-eq</span> <span style="color: #008080">[Microsoft.Synchronization.Files.ChangeType]</span><span style="color: #a9a9a9">::</span><span style="color: #000000">Rename</span> <span style="color: #000000">}</span> <span style="color: #000000">{</span><span style="color: #008080">[string[]]</span><span style="color: #ff4500">$global:FileSyncReport</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Renamed</span> <span style="color: #a9a9a9">+=</span> <span style="color: #ff4500">$argument</span><span style="color: #a9a9a9">.</span><span style="color: #000000">OldFilePath</span><span style="color: #000000">}</span>
                <span style="color: #000000">}</span>
            <span style="color: #000000">}</span>            

            <span style="color: #ff4500">$SkippedChangeAction</span> <span style="color: #a9a9a9">=</span> <span style="color: #000000">{</span>
                <span style="color: #008080">[string[]]</span><span style="color: #ff4500">$global:FileSyncReport</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Skipped</span> <span style="color: #a9a9a9">+=</span> <span style="color: #ff4500">$event</span><span style="color: #a9a9a9">.</span><span style="color: #000000">SourceEventArgs</span><span style="color: #a9a9a9">.</span><span style="color: #000000">CurrentFilePath</span>            

                <span style="color: #00008b">if</span> <span style="color: #000000">(</span><span style="color: #ff4500">$event</span><span style="color: #a9a9a9">.</span><span style="color: #000000">SourceEventArgs</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Exception</span> <span style="color: #a9a9a9">-ne</span> <span style="color: #ff4500">$null</span><span style="color: #000000">)</span>
                <span style="color: #000000">{</span>
                    <span style="color: #0000ff">Write-Error</span> <span style="color: #8b0000">'['</span> <span style="color: #8a2be2">+</span> <span style="color: #8b0000">"$($event.SourceEventArgs.Exception.Message)"</span> <span style="color: #8a2be2">+']'</span>
                <span style="color: #000000">}</span>
            <span style="color: #000000">}</span>            

            <span style="color: #006400"># Create source provider and register change events for it</span>            

            <span style="color: #ff4500">$sourceProvider</span> <span style="color: #a9a9a9">=</span> <span style="color: #0000ff">New-Object</span> <span style="color: #8a2be2">Microsoft.Synchronization.Files.FileSyncProvider</span> <span style="color: #000080">-ArgumentList</span> <span style="color: #ff4500">$SourcePath</span><span style="color: #a9a9a9">,</span> <span style="color: #ff4500">$filter</span><span style="color: #a9a9a9">,</span> <span style="color: #ff4500">$options</span>
            <span style="color: #ff4500">$AppliedChangeJobs</span> <span style="color: #a9a9a9">+=</span> <span style="color: #0000ff">Register-ObjectEvent</span> <span style="color: #000080">-InputObject</span> <span style="color: #ff4500">$SourceProvider</span> <span style="color: #000080">-EventName</span> <span style="color: #8a2be2">AppliedChange</span> <span style="color: #000080">-Action</span> <span style="color: #ff4500">$AppliedChangeAction</span>
            <span style="color: #ff4500">$AppliedChangeJobs</span> <span style="color: #a9a9a9">+=</span> <span style="color: #0000ff">Register-ObjectEvent</span> <span style="color: #000080">-InputObject</span> <span style="color: #ff4500">$SourceProvider</span> <span style="color: #000080">-EventName</span> <span style="color: #8a2be2">SkippedChange</span> <span style="color: #000080">-Action</span> <span style="color: #ff4500">$SkippedChangeAction</span>             

            <span style="color: #ff4500">$ApplyChangeJobs</span> <span style="color: #a9a9a9">+=</span> <span style="color: #ff4500">$SourceApplyChangeJob</span>            

            <span style="color: #006400"># Create destination provider and register change events for it</span>
            <span style="color: #ff4500">$destinationProvider</span> <span style="color: #a9a9a9">=</span> <span style="color: #0000ff">New-Object</span> <span style="color: #8a2be2">Microsoft.Synchronization.Files.FileSyncProvider</span> <span style="color: #000080">-ArgumentList</span> <span style="color: #ff4500">$DestinationPath</span><span style="color: #a9a9a9">,</span> <span style="color: #ff4500">$filter</span><span style="color: #a9a9a9">,</span> <span style="color: #ff4500">$options</span>
            <span style="color: #ff4500">$AppliedChangeJobs</span> <span style="color: #a9a9a9">+=</span> <span style="color: #0000ff">Register-ObjectEvent</span> <span style="color: #000080">-InputObject</span> <span style="color: #ff4500">$destinationProvider</span> <span style="color: #000080">-EventName</span> <span style="color: #8a2be2">AppliedChange</span> <span style="color: #000080">-Action</span> <span style="color: #ff4500">$AppliedChangeAction</span>
            <span style="color: #ff4500">$AppliedChangeJobs</span> <span style="color: #a9a9a9">+=</span> <span style="color: #0000ff">Register-ObjectEvent</span> <span style="color: #000080">-InputObject</span> <span style="color: #ff4500">$destinationProvider</span> <span style="color: #000080">-EventName</span> <span style="color: #8a2be2">SkippedChange</span> <span style="color: #000080">-Action</span> <span style="color: #ff4500">$SkippedChangeAction</span>            

            <span style="color: #ff4500">$ApplyChangeJobs</span> <span style="color: #a9a9a9">+=</span> <span style="color: #ff4500">$DestApplyChangeJob</span>            

            <span style="color: #006400"># Use scriptblocks for the SyncCallbacks for conflicting items.</span>
            <span style="color: #ff4500">$ItemConflictAction</span> <span style="color: #a9a9a9">=</span>   <span style="color: #000000">{</span>
                <span style="color: #ff4500">$event</span><span style="color: #a9a9a9">.</span><span style="color: #000000">SourceEventArgs</span><span style="color: #a9a9a9">.</span><span style="color: #000000">SetResolutionAction</span><span style="color: #000000">(</span><span style="color: #008080">[Microsoft.Synchronization.ConflictResolutionAction]</span><span style="color: #a9a9a9">::</span><span style="color: #000000">SourceWins</span><span style="color: #000000">)</span>
                <span style="color: #008080">[string[]]</span><span style="color: #ff4500">$global:FileSyncReport</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Conflicted</span> <span style="color: #a9a9a9">+=</span> <span style="color: #ff4500">$event</span><span style="color: #a9a9a9">.</span><span style="color: #000000">SourceEventArgs</span><span style="color: #a9a9a9">.</span><span style="color: #000000">DestinationChange</span><span style="color: #a9a9a9">.</span><span style="color: #000000">ItemId</span>
            <span style="color: #000000">}</span>
            <span style="color: #ff4500">$ItemConstraintAction</span> <span style="color: #a9a9a9">=</span> <span style="color: #000000">{</span>
                <span style="color: #ff4500">$event</span><span style="color: #a9a9a9">.</span><span style="color: #000000">SourceEventArgs</span><span style="color: #a9a9a9">.</span><span style="color: #000000">SetResolutionAction</span><span style="color: #000000">(</span><span style="color: #008080">[Microsoft.Synchronization.ConstraintConflictResolutionAction]</span><span style="color: #a9a9a9">::</span><span style="color: #000000">SourceWins</span><span style="color: #000000">)</span>
                <span style="color: #008080">[string[]]</span><span style="color: #ff4500">$global:FileSyncReport</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Constrained</span> <span style="color: #a9a9a9">+=</span> <span style="color: #ff4500">$event</span><span style="color: #a9a9a9">.</span><span style="color: #000000">SourceEventArgs</span><span style="color: #a9a9a9">.</span><span style="color: #000000">DestinationChange</span><span style="color: #a9a9a9">.</span><span style="color: #000000">ItemId</span>
            <span style="color: #000000">}</span>            

            <span style="color: #006400">#Configure the events for conflicts or constraints for the source and destination providers</span>
            <span style="color: #ff4500">$destinationCallbacks</span> <span style="color: #a9a9a9">=</span> <span style="color: #ff4500">$destinationProvider</span><span style="color: #a9a9a9">.</span><span style="color: #000000">DestinationCallbacks</span>
            <span style="color: #ff4500">$AppliedChangeJobs</span> <span style="color: #a9a9a9">+=</span> <span style="color: #0000ff">Register-ObjectEvent</span> <span style="color: #000080">-InputObject</span> <span style="color: #ff4500">$destinationCallbacks</span> <span style="color: #000080">-EventName</span> <span style="color: #8a2be2">ItemConflicting</span> <span style="color: #000080">-Action</span> <span style="color: #ff4500">$ItemConflictAction</span>
            <span style="color: #ff4500">$AppliedChangeJobs</span> <span style="color: #a9a9a9">+=</span> <span style="color: #0000ff">Register-ObjectEvent</span> <span style="color: #000080">-InputObject</span> <span style="color: #ff4500">$destinationCallbacks</span> <span style="color: #000080">-EventName</span> <span style="color: #8a2be2">ItemConstraint</span> <span style="color: #000080">-Action</span> <span style="color: #ff4500">$ItemConstraintAction</span>             

            <span style="color: #ff4500">$sourceCallbacks</span> <span style="color: #a9a9a9">=</span> <span style="color: #ff4500">$SourceProvider</span><span style="color: #a9a9a9">.</span><span style="color: #000000">DestinationCallbacks</span>
            <span style="color: #ff4500">$AppliedChangeJobs</span> <span style="color: #a9a9a9">+=</span> <span style="color: #0000ff">Register-ObjectEvent</span> <span style="color: #000080">-InputObject</span> <span style="color: #ff4500">$sourceCallbacks</span> <span style="color: #000080">-EventName</span> <span style="color: #8a2be2">ItemConflicting</span> <span style="color: #000080">-Action</span> <span style="color: #ff4500">$ItemConflictAction</span>
            <span style="color: #ff4500">$AppliedChangeJobs</span> <span style="color: #a9a9a9">+=</span> <span style="color: #0000ff">Register-ObjectEvent</span> <span style="color: #000080">-InputObject</span> <span style="color: #ff4500">$sourceCallbacks</span> <span style="color: #000080">-EventName</span> <span style="color: #8a2be2">ItemConstraint</span> <span style="color: #000080">-Action</span> <span style="color: #ff4500">$ItemConstraintAction</span>             

            <span style="color: #006400"># Create the agent that will perform the file sync</span>
            <span style="color: #ff4500">$agent</span> <span style="color: #a9a9a9">=</span> <span style="color: #0000ff">New-Object</span>  <span style="color: #8a2be2">Microsoft.Synchronization.SyncOrchestrator</span>
            <span style="color: #ff4500">$agent</span><span style="color: #a9a9a9">.</span><span style="color: #000000">LocalProvider</span> <span style="color: #a9a9a9">=</span> <span style="color: #ff4500">$sourceProvider</span>
            <span style="color: #ff4500">$agent</span><span style="color: #a9a9a9">.</span><span style="color: #000000">RemoteProvider</span> <span style="color: #a9a9a9">=</span> <span style="color: #ff4500">$destinationProvider</span>            

            <span style="color: #006400"># Upload changes from the source to the destination.</span>
            <span style="color: #ff4500">$agent</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Direction</span> <span style="color: #a9a9a9">=</span> <span style="color: #008080">[Microsoft.Synchronization.SyncDirectionOrder]</span><span style="color: #a9a9a9">::</span><span style="color: #000000">Upload</span>            

            <span style="color: #0000ff">Write-Host</span> <span style="color: #8b0000">"Synchronizing changes from $($sourceProvider.RootDirectoryPath) to replica: $($destinationProvider.RootDirectoryPath)"</span>
            <span style="color: #ff4500">$agent</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Synchronize</span><span style="color: #000000">(</span><span style="color: #000000">)</span><span style="color: #000000">;</span>
        <span style="color: #000000">}</span>
        <span style="color: #00008b">finally</span>
        <span style="color: #000000">{</span>
            <span style="color: #006400"># Release resources.</span>
            <span style="color: #00008b">if</span> <span style="color: #000000">(</span><span style="color: #ff4500">$sourceProvider</span> <span style="color: #a9a9a9">-ne</span> <span style="color: #ff4500">$null</span><span style="color: #000000">)</span> <span style="color: #000000">{</span><span style="color: #ff4500">$sourceProvider</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Dispose</span><span style="color: #000000">(</span><span style="color: #000000">)</span><span style="color: #000000">}</span>
            <span style="color: #00008b">if</span> <span style="color: #000000">(</span><span style="color: #ff4500">$destinationProvider</span> <span style="color: #a9a9a9">-ne</span> <span style="color: #ff4500">$null</span><span style="color: #000000">)</span> <span style="color: #000000">{</span><span style="color: #ff4500">$destinationProvider</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Dispose</span><span style="color: #000000">(</span><span style="color: #000000">)</span><span style="color: #000000">}</span>
        <span style="color: #000000">}</span>
    <span style="color: #000000">}</span>            

    <span style="color: #006400"># Set options for the synchronization session. In this case, options specify</span>
    <span style="color: #006400"># that the application will explicitly call FileSyncProvider.DetectChanges, and</span>
    <span style="color: #006400"># that items should be moved to the Recycle Bin instead of being permanently deleted.</span>            

    <span style="color: #ff4500">$options</span> <span style="color: #a9a9a9">=</span> <span style="color: #008080">[Microsoft.Synchronization.Files.FileSyncOptions]</span><span style="color: #a9a9a9">::</span><span style="color: #000000">ExplicitDetectChanges</span>
    <span style="color: #ff4500">$options</span> <span style="color: #a9a9a9">=</span> <span style="color: #ff4500">$options</span> <span style="color: #a9a9a9">-bor</span> <span style="color: #008080">[Microsoft.Synchronization.Files.FileSyncOptions]</span><span style="color: #a9a9a9">::</span><span style="color: #000000">RecycleDeletedFiles</span>
    <span style="color: #ff4500">$options</span> <span style="color: #a9a9a9">=</span> <span style="color: #ff4500">$options</span> <span style="color: #a9a9a9">-bor</span> <span style="color: #008080">[Microsoft.Synchronization.Files.FileSyncOptions]</span><span style="color: #a9a9a9">::</span><span style="color: #000000">RecyclePreviousFileOnUpdates</span>
    <span style="color: #ff4500">$options</span> <span style="color: #a9a9a9">=</span> <span style="color: #ff4500">$options</span> <span style="color: #a9a9a9">-bor</span> <span style="color: #008080">[Microsoft.Synchronization.Files.FileSyncOptions]</span><span style="color: #a9a9a9">::</span><span style="color: #000000">RecycleConflictLoserFiles</span>
<span style="color: #000000">}</span>
<span style="color: #00008b">process</span>
<span style="color: #000000">{</span>
    <span style="color: #ff4500">$filter</span> <span style="color: #a9a9a9">=</span> <span style="color: #0000ff">New-Object</span> <span style="color: #8a2be2">Microsoft.Synchronization.Files.FileSyncScopeFilter</span>
    <span style="color: #00008b">if</span> <span style="color: #000000">(</span><span style="color: #ff4500">$FileNameFilter</span><span style="color: #a9a9a9">.</span><span style="color: #000000">count</span> <span style="color: #a9a9a9">-gt</span> <span style="color: #800080">0</span><span style="color: #000000">)</span>
    <span style="color: #000000">{</span>
       <span style="color: #ff4500">$FileNameFilter</span> <span style="color: #a9a9a9">|</span> <span style="color: #0000ff">ForEach-Object</span> <span style="color: #000000">{</span> <span style="color: #ff4500">$filter</span><span style="color: #a9a9a9">.</span><span style="color: #000000">FileNameExcludes</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Add</span><span style="color: #000000">(</span><span style="color: #ff4500">$_</span><span style="color: #000000">)</span> <span style="color: #000000">}</span>
    <span style="color: #000000">}</span>
    <span style="color: #00008b">if</span> <span style="color: #000000">(</span><span style="color: #ff4500">$SubdirectoryNameFilter</span><span style="color: #a9a9a9">.</span><span style="color: #000000">count</span> <span style="color: #a9a9a9">-gt</span> <span style="color: #800080">0</span><span style="color: #000000">)</span>
    <span style="color: #000000">{</span>
       <span style="color: #ff4500">$SubdirectoryNameFilter</span> <span style="color: #a9a9a9">|</span> <span style="color: #0000ff">ForEach-Object</span> <span style="color: #000000">{</span> <span style="color: #ff4500">$filter</span><span style="color: #a9a9a9">.</span><span style="color: #000000">SubdirectoryExcludes</span><span style="color: #a9a9a9">.</span><span style="color: #000000">Add</span><span style="color: #000000">(</span><span style="color: #ff4500">$_</span><span style="color: #000000">)</span> <span style="color: #000000">}</span>
    <span style="color: #000000">}</span>            

    <span style="color: #006400"># Perform the detect changes operation on the two file locations</span>
    <span style="color: #0000ff">Get-FileSystemChange</span> <span style="color: #ff4500">$SourcePath</span> <span style="color: #ff4500">$filter</span> <span style="color: #ff4500">$options</span>
    <span style="color: #0000ff">Get-FileSystemChange</span> <span style="color: #ff4500">$DestinationPath</span> <span style="color: #ff4500">$filter</span> <span style="color: #ff4500">$options</span>            

    <span style="color: #006400"># Reporting Object - using the global scope so that it can be updated by the event scriptblocks.</span>
    <span style="color: #ff4500">$global:FileSyncReport</span> <span style="color: #a9a9a9">=</span> <span style="color: #0000ff">New-Object</span> <span style="color: #8a2be2">PSObject</span> <span style="color: #a9a9a9">|</span>
        <span style="color: #0000ff">Select-Object</span> <span style="color: #8a2be2">SourceStats</span><span style="color: #a9a9a9">,</span> <span style="color: #8a2be2">DestinationStats</span><span style="color: #a9a9a9">,</span> <span style="color: #8a2be2">Created</span><span style="color: #a9a9a9">,</span> <span style="color: #8a2be2">Deleted</span><span style="color: #a9a9a9">,</span> <span style="color: #8a2be2">Overwritten</span><span style="color: #a9a9a9">,</span> <span style="color: #8a2be2">Renamed</span><span style="color: #a9a9a9">,</span> <span style="color: #8a2be2">Skipped</span><span style="color: #a9a9a9">,</span> <span style="color: #8a2be2">Conflicted</span><span style="color: #a9a9a9">,</span> <span style="color: #8a2be2">Constrained</span>            

    <span style="color: #006400"># We don't need to pass any filters here, since we are using the file detection that was previously completed.</span>
    <span style="color: #006400"># this will only </span>
    <span style="color: #ff4500">$global:FileSyncReport</span><span style="color: #a9a9a9">.</span><span style="color: #000000">SourceStats</span> <span style="color: #a9a9a9">=</span> <span style="color: #0000ff">Invoke-OneWayFileSync</span> <span style="color: #000080">-SourcePath</span> <span style="color: #ff4500">$SourcePath</span> <span style="color: #000080">-DestinationPath</span> <span style="color: #ff4500">$DestinationPath</span> <span style="color: #000080">-Filter</span> <span style="color: #ff4500">$null</span> <span style="color: #000080">-Options</span> <span style="color: #ff4500">$options</span>
    <span style="color: #ff4500">$global:FileSyncReport</span><span style="color: #a9a9a9">.</span><span style="color: #000000">DestinationStats</span> <span style="color: #a9a9a9">=</span> <span style="color: #0000ff">Invoke-OneWayFileSync</span> <span style="color: #000080">-SourcePath</span> <span style="color: #ff4500">$DestinationPath</span> <span style="color: #000080">-DestinationPath</span> <span style="color: #ff4500">$SourcePath</span> <span style="color: #000080">-Filter</span> <span style="color: #ff4500">$null</span> <span style="color: #000080">-Options</span> <span style="color: #ff4500">$options</span>            

    <span style="color: #006400"># Write result to pipeline</span>
    <span style="color: #0000ff">Write-Output</span> <span style="color: #ff4500">$global:FileSyncReport</span>
<span style="color: #000000">}</span></pre>
<h3 class="PowerShellColorizedScript"><span style="color: #000000"><a href="http://download.usepowershell.com/Invoke-SyncFrameworkSample.zip" target="_blank">Download Invoke-SyncFrameworkSample.zip</a></span></h3>
]]></content:encoded>
			<wfw:commentRss>http://blog.usepowershell.com/2009/11/using-the-sync-framework-from-powershell/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Deep Dive: Error Handling &#8211; Error Types (part 1)</title>
		<link>http://blog.usepowershell.com/2009/07/deep-dive-error-handling-error-types-part-1/</link>
		<comments>http://blog.usepowershell.com/2009/07/deep-dive-error-handling-error-types-part-1/#comments</comments>
		<pubDate>Tue, 21 Jul 2009 12:00:00 +0000</pubDate>
		<dc:creator>Steven Murawski</dc:creator>
				<category><![CDATA[.NET Framework]]></category>
		<category><![CDATA[Base Class Libraries]]></category>
		<category><![CDATA[Deep Dive]]></category>
		<category><![CDATA[Error Handling]]></category>
		<category><![CDATA[PowerShell Version 1]]></category>
		<category><![CDATA[PowerShell Version 2]]></category>

		<guid isPermaLink="false">http://blog.usepowershell.com/2009/07/deep-dive-error-handling-error-types-part-1/</guid>
		<description><![CDATA[I started looking a little deeper at error handling in PowerShell after this StackOverflow question. PowerShell has two kinds of errors – terminating errors and non-terminating errors. Terminating errors are the errors that can stop command execution cold.  Non-terminating errors provided an additional challenge, as you need to be notified of failed operations and continue [...]]]></description>
			<content:encoded><![CDATA[<p>I started looking a little deeper at error handling in PowerShell after <a href="http://stackoverflow.com/questions/1142211/try-catch-does-not-seem-to-have-an-effect" target="_blank">this StackOverflow question</a>.</p>
<p>PowerShell has two kinds of errors – terminating errors and non-terminating errors.</p>
<p>Terminating errors are the errors that can stop command execution cold.  Non-terminating errors provided an additional challenge, as you need to be notified of failed operations and continue with pipeline operations.  To deal with this issue and to provide additional output options, PowerShell employs the concept of streams.  There are three additional streams (other than the primary pipeline stream) available in PowerShell – Verbose, Warning, and Error (and .  We’ll be concerning ourselves with the output from the Error stream.</p>
<p>There are some <a href="http://technet.microsoft.com/en-us/library/dd347675.aspx" target="_blank">automatic variables</a> in the shell that deal with errors as well.  $ErrorActionPreference is a variable that describes how PowerShell will treat non-terminating errors.  $ErrorActionPreference has four options: “Continue” (the default), “SilentlyContinue”, “Inquire”, and “Stop”.  $error is an array of all the errors that have occurred in the current session up to the number specified in $MaximumErrorCount.  $? is a boolean value that is $true if the previous operation succeeded and $false if it did not.</p>
<p>PowerShell does have some built in flexibility to turn non-terminating errors into terminating errors.  Based on our setting of $ErrorActionPreference, PowerShell will treat a non-terminating error differently.  If $ErrorActionPreference is set to &#8216;”Stop”, PowerShell will treat the errors from that scope and all sub scopes (unless explicitly overridden) as terminating errors.  If “Inquire” is chosen as the $ErrorActionPreference, then PowerShell will prompt the user at the console upon each error to ask whether it should continue (treat as non-terminating) or halt (treat as terminating), as well as providing an option to drop into a nested prompt.</p>
<p>$ErrorActionPreference is a global preference that can be set, but the PowerShell runtime also allows more granular control by providing <a href="http://technet.microsoft.com/en-us/library/dd315352.aspx" target="_blank">common parameters</a> for -ErrorAction and -ErrorVariable (shorthand -EA and –EV) which allow you to determine per cmdlet (and in V2 per advanced function) how errors should be handled.  The –ErrorAction parameter takes the same options as $ErrorActionPreference.</p>
<p>So what happens when you encounter an error?</p>
<p>If you hit a terminating error, your script, function, or command will stop.  The error will be logged to the $error variable and written to the error stream.  The $? will be set to false.  You can use the <a href="http://technet.microsoft.com/en-us/library/dd347548.aspx" target="_blank">trap construct</a> (or the <a href="http://technet.microsoft.com/en-us/library/dd315350.aspx" target="_blank">try/catch/finally construct</a> in V2) to deal with terminating errors and we’ll cover that further in the fourth post in this series.</p>
<p>If you hit a non-terminating error, the result will depend on the $ErrorActionPreference in the scope or the –ErrorAction parameter.  If the $ErrorActionPreference or –ErrorAction parameter is set to ‘Continue’, the error will be written to the error stream, added to the $error array, and the $? will be set to $false.  ‘SilentlyContinue’ will not write an error to the Error stream, but $error and $? are updated.  Finally, ‘Inquire’ provides you an option at each error as to whether to treat it as terminating or non-terminating.  If treated as a non-terminating error, the error will be treated like the $ErrorActionPreference or –ErrorAction parameter is ‘Continue’.</p>
<p>Now, I’ve mentioned that some terminating and non-terminating errors both write to the Error stream, so where does that actually get reported back to the user?  If an error has been written to the error stream, it will be written to the output stream (which may surface differently based on the PowerShell host) separately from the pipeline output unless it is redirected.  This means that the exception objects, which are how the errors are represented, are not saved to a variable if you are assigning the pipeline output to a variable.</p>
<p>For example:</p>
<p>$results = Get-WMIObject Win32_Bios –ComputerName localhost, ComputerThatDoesNotExist<br />
Get-WmiObject : The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)<br />
At line:1 char:22<br />
+ $results = Get-WmiObject  &lt;&lt;&lt;&lt; Win32_Bios -ComputerName localhost, ComputerThatDoesNotExist</p>
<p>creates this output to the screen, but $results will only hold the results of the successful WMI query.  This is where the –ErrorVariable comes in.  You can specify a variable to hold the exceptions generated by a particular cmdlet (or in V2 advanced function).  Specifying a variable does not remove an item from being written to the error stream and displayed as output.</p>
<p>In a console session, you can redirect the error stream with the redirection operators ( 2&gt; or 2&gt;&gt;) or you can merge the error stream with the output stream (2&gt;&amp;1) and write the output to a file, the pipeline, or assign it to a variable.</p>
<p>Up next:</p>
<ul>
<li>Error Objects</li>
<li>Tracing Errors</li>
<li>Trapping Errors</li>
<li>Reporting Errors</li>
</ul>
<p>Other great <a href="http://support.microsoft.com/kb/968929" target="_blank">PowerShell</a> Error Handling posts:</p>
<ul>
<li><a href="http://huddledmasses.org/trap-exception-in-powershell/">http://huddledmasses.org/trap-exception-in-powershell/</a></li>
<li><a href="http://blogs.msdn.com/powershell/archive/2006/11/03/erroraction-and-errorvariable.aspx">http://blogs.msdn.com/powershell/archive/2006/11/03/erroraction-and-errorvariable.aspx</a></li>
<li><a href="http://tfl09.blogspot.com/2009/01/error-handling-with-powershell.html">http://tfl09.blogspot.com/2009/01/error-handling-with-powershell.html</a></li>
<li><a href="http://weblogs.asp.net/adweigert/archive/2007/10/10/powershell-try-catch-finally-comes-to-life.aspx">http://weblogs.asp.net/adweigert/archive/2007/10/10/powershell-try-catch-finally-comes-to-life.aspx</a></li>
<li><a href="http://powershell.com/cs/blogs/ebook/archive/2009/03/30/chapter-11-finding-and-avoiding-errors.aspx">http://powershell.com/cs/blogs/ebook/archive/2009/03/30/chapter-11-finding-and-avoiding-errors.aspx</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.usepowershell.com/2009/07/deep-dive-error-handling-error-types-part-1/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Exploring the .NET Framework with PowerShell &#8211; Garbage Collection (Part 6)</title>
		<link>http://blog.usepowershell.com/2009/07/exploring-the-net-framework-with-powershell-garbage-collection-part-6/</link>
		<comments>http://blog.usepowershell.com/2009/07/exploring-the-net-framework-with-powershell-garbage-collection-part-6/#comments</comments>
		<pubDate>Tue, 07 Jul 2009 12:00:00 +0000</pubDate>
		<dc:creator>Steven Murawski</dc:creator>
				<category><![CDATA[.NET Framework]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://blog.usepowershell.com/2009/07/exploring-the-net-framework-with-powershell-garbage-collection-part-6/</guid>
		<description><![CDATA[Garbage collection is a process that the .NET Framework (upon which the PowerShell runtime works) uses to manage memory.&#160; The garbage collection (for applications – services are handled a bit differently) process basically covers X steps: Identify objects that won’t be used Delete them from memory Compact the space to make room for new objects [...]]]></description>
			<content:encoded><![CDATA[<p>Garbage collection is a process that the .NET Framework (upon which the PowerShell runtime works) uses to manage memory.&#160; The garbage collection (for applications – services are handled a bit differently) process basically covers X steps:</p>
<ol>
<li>Identify objects that won’t be used </li>
<li>Delete them from memory </li>
<li>Compact the space to make room for new objects </li>
</ol>
<p>The first step is the critical point for PowerShell users.&#160; You may have noticed how the memory used in a PowerShell session can steadily climb (or suddenly climb if you’re dealing with a large number of objects).&#160; I talked about that in <a href="http://blog.usepowershell.com/2009/03/tip-free-up-some-memory/" target="_blank">this tip</a>.&#160; The .NET garbage collector looks for objects that are still in use or could possibly be in use in the near future (this is a gross oversimplification &#8211; if you are really interested in a detailed explanation of how garbage collection works in the .NET Framework, <a href="http://www.simple-talk.com/content/article.aspx?article=737" target="_blank">check out this article</a>.) </p>
<p>What this means to scripters who are running into memory pressure issues is that the garbage collector will not reclaim any objects you have actively referenced (meaning that you’ve assigned them to a variable) in your current or higher scope.&#160; </p>
<p>Since this can sound a bit convoluted let’s look at an example.&#160; </p>
<p>I read a large file to parse it and leave the contents of the original stored in a variable</p>
<p>PS&gt; $MyLargeFile =&#160; <a href="http://go.microsoft.com/fwlink/?LinkID=113310">Get-Content</a> MyLargeFile.txt    <br />PS&gt; Foreach ($line in $MyLargeFile) {    <br />DoSomething $line | <a href="http://go.microsoft.com/fwlink/?LinkID=113363">Out-File</a> NewUpdatedLargeFile.txt    <br />}</p>
<p>One of the problems with the above pattern is that the original file remains saved in memory and doesn’t get released unless you explicitly remove the reference, either by using <a href="http://go.microsoft.com/fwlink/?LinkID=113380">Remove-Variable</a> or <a href="http://go.microsoft.com/fwlink/?LinkID=113373">Remove-Item</a> or by changing what $MyLargeFile points to by assigning another value to it.&#160; </p>
<p>This isn’t VBScript where you have to set values to “Nothing”, but you should be aware of what larger object sets you are retaining in memory.&#160; </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.usepowershell.com/2009/07/exploring-the-net-framework-with-powershell-garbage-collection-part-6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Exploring the .NET Framework with PowerShell – Namespaces (Part 5)</title>
		<link>http://blog.usepowershell.com/2009/04/exploring-the-net-framework-with-powershell-namespaces-part-5/</link>
		<comments>http://blog.usepowershell.com/2009/04/exploring-the-net-framework-with-powershell-namespaces-part-5/#comments</comments>
		<pubDate>Mon, 27 Apr 2009 12:00:00 +0000</pubDate>
		<dc:creator>Steven Murawski</dc:creator>
				<category><![CDATA[.NET Framework]]></category>
		<category><![CDATA[Base Class Libraries]]></category>
		<category><![CDATA[Introduction]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://blog.usepowershell.com/?p=115</guid>
		<description><![CDATA[One concept that is central to the understanding of the layout of classes in the Base Class Libraries is the Namespace.  Namespaces are a method of providing context for classes (and other constructs like Enums and Structs), allowing developers to group related classes and not worry about name collisions with development in other areas. In [...]]]></description>
			<content:encoded><![CDATA[<p>One concept that is central to the understanding of the layout of classes in the <a href="http://blog.usepowershell.com/2009/02/exploring-the-net-framework-with-powershell-terminology-part-1/" target="_blank">Base Class Libraries</a> is the Namespace.  Namespaces are a method of providing context for classes (and other constructs like Enums and Structs), allowing developers to group related classes and not worry about name collisions with development in other areas.</p>
<p>In the Base Class Libraries, the root namespace is the System namespace.  The System namespace defines a large amount of the base types, like <a href="http://msdn.microsoft.com/en-us/library/system.object.aspx" target="_blank">Object</a> (which all classes derive from), <a href="http://msdn.microsoft.com/en-us/library/system.string.aspx" target="_blank">String</a>, <a href="http://msdn.microsoft.com/en-us/library/system.datetime.aspx" target="_blank">DateTime</a>, <a href="http://msdn.microsoft.com/en-us/library/system.boolean.aspx" target="_blank">Boolean</a>, and <a href="http://msdn.microsoft.com/en-us/library/system.aspx" target="_blank">numerous others</a>.  When you specify types, <a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/download.mspx" target="_blank">PowerShell</a> can infer the “System” part.</p>
<p>Example:</p>
<blockquote><p>PS C:\scripts\PowerShell&gt; $random = <a href="http://technet.microsoft.com/en-us/library/d203c4ab-2d57-4103-a04e-d7869d06931e" target="_blank">New-Object</a> –TypeName <a href="http://msdn.microsoft.com/en-us/library/system.random.aspx" target="_blank">Random</a></p></blockquote>
<p>is the same as</p>
<blockquote><p>PS C:\scripts\PowerShell&gt; $random = <a href="http://technet.microsoft.com/en-us/library/d203c4ab-2d57-4103-a04e-d7869d06931e" target="_blank">New-Object</a> –TypeName <a href="http://msdn.microsoft.com/en-us/library/system.random.aspx" target="_blank">System.Random</a></p></blockquote>
<p>Namespaces are hierarchical, except in naming convention. The representation of a file in PowerShell is a great example.  A file object is represented in PowerShell as a <a href="http://msdn.microsoft.com/en-us/library/system.io.fileinfo.aspx" target="_blank">System.IO.FileInfo</a> object.  The <a href="http://msdn.microsoft.com/en-us/library/system.io.fileinfo.aspx" target="_blank">FileInfo</a> class lives in the <a href="http://msdn.microsoft.com/en-us/library/system.io.aspx" target="_blank">System.IO</a> namespace, which is a separate namespace than the <a href="http://msdn.microsoft.com/en-us/library/system.aspx" target="_blank">System</a> namespace.  There is a hierarchical impression implied, but that is solely through naming convention.</p>
<p>The CLR (Common Language Runtime) does not care about namespaces, only the fully qualified name of the class, so why use namespaces at all?</p>
<p>Namespaces are a convenience for developers, as languages like C# and VB.NET have language constructs that allow the developer to not have to use the fully qualified type name every time that is needed to be referenced.  C# provides the “<a href="http://msdn.microsoft.com/en-us/library/aa664766(VS.71).aspx" target="_blank">using</a>” syntax and VB.NET has the “<a href="http://msdn.microsoft.com/en-us/library/zt9tafza(VS.80).aspx" target="_blank">imports</a>” syntax.</p>
<p>How does this apply to PowerShell?</p>
<p>PowerShell does not currently have a “using” or “imports” syntax or language feature, but there are a couple of workarounds.  You can use variables holding the namespace and string concatenation to save some typing</p>
<blockquote><p>PS C:\scripts\PowerShell&gt; $netinfo = &#8216;System.Net.NetworkInformation&#8217;<br />
PS C:\scripts\PowerShell&gt; $ping = New-Object &#8220;$netinfo.ping&#8221;<br />
PS C:\scripts\PowerShell&gt; $ping.gettype()<br />
IsPublic IsSerial Name           BaseType<br />
&#8212;&#8212;&#8211; &#8212;&#8212;&#8211; &#8212;-                &#8212;&#8212;&#8211;<br />
True     False    Ping            System.ComponentModel.Component</p></blockquote>
<p>This doesn’t work with type accelerators though (at least in V1)..  V2 CTP3 has some other options and <a href="http://www.nivot.org/2008/12/25/ListOfTypeAcceleratorsForPowerShellCTP3.aspx" target="_blank">Oisin Grehan has a great discussion on how to find the type accelerators and add your own.</a></p>
<p>Another option would be to create a function to wrap the creation of objects for particular namespaces.</p>
<p>Use-Namespace is a function I came up with to create a function to wrap New-Object for specific namespaces.</p>
<p>The useage of Use-Namespace is<br />
PS C:\scripts\PowerShell&gt;Use-Namespace System.IO, System.Net<br />
PS C:\scripts\PowerShell&gt;$memorystream = New-System.IOObject MemoryStream<br />
PS C:\scripts\PowerShell&gt;$memorystream.GetType()<br />
PS C:\scripts\PowerShell&gt; $memorystream.gettype()<br />
IsPublic IsSerial  Name                    BaseType<br />
&#8212;&#8212;&#8211; &#8212;&#8212;&#8211;   &#8212;-                         &#8212;&#8212;&#8211;<br />
True     True     MemoryStream      System.IO.Stream</p>
<p>And the function is here..</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
</pre></td><td class="code"><pre class="powershell" style="font-family:monospace;"><span style="color: #0000FF;">function</span> Use<span style="color: pink;">-</span>Namespace<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
<span style="color: #000000;">&#123;</span>
  <span style="color: #0000FF;">param</span> <span style="color: #000000;">&#40;</span><span style="color: #000000;">&#91;</span><span style="color: #008080;">string</span><span style="color: #000000;">&#91;</span><span style="color: #000000;">&#93;</span><span style="color: #000000;">&#93;</span><span style="color: #800080;">$Namespace</span><span style="color: #000000;">&#41;</span>
  BEGIN
  <span style="color: #000000;">&#123;</span>
    <span style="color: #0000FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #800080;">$Namespace</span>.length <span style="color: #FF0000;">-gt</span> <span style="color: #000000;">0</span><span style="color: #000000;">&#41;</span>
    <span style="color: #000000;">&#123;</span>
      <span style="color: #800080;">$Namespace</span> <span style="color: pink;">|</span> Use<span style="color: pink;">-</span>Namespace
    <span style="color: #000000;">&#125;</span>
  <span style="color: #000000;">&#125;</span>
  PROCESS
  <span style="color: #000000;">&#123;</span>
    <span style="color: #0000FF;">if</span> <span style="color: #000000;">&#40;</span><span style="color: #000080;">$_</span> <span style="color: #FF0000;">-ne</span> <span style="color: #800080;">$null</span><span style="color: #000000;">&#41;</span>
    <span style="color: #000000;">&#123;</span>
      <span style="color: #800080;">$NS</span> <span style="color: pink;">=</span> <span style="color: #000080;">$_</span>
      <span style="color: #800080;">$NSObject</span> <span style="color: pink;">=</span> <span style="color: #800000;">&quot;$NS&quot;</span> <span style="color: pink;">+</span> <span style="color: #800000;">&quot;Object&quot;</span>
      <span style="color: #800080;">$function</span> <span style="color: pink;">=</span> <span style="color: pink;">@</span><span style="color: #800000;">&quot;
param (<span style="color: #008080; font-weight: bold;">`$</span>Class, [string[]]<span style="color: #008080; font-weight: bold;">`$</span>ArgumentList)
if (<span style="color: #008080; font-weight: bold;">`$</span>ArgumentList.length -gt 0)
{
return New-Object -TypeName &quot;</span><span style="color: #800080;">$NS</span>.`$Class<span style="color: #800000;">&quot; -ArgumentList <span style="color: #008080; font-weight: bold;">`$</span>ArgumentList
}
else
{
return New-Object -TypeName &quot;</span><span style="color: #800080;">$NS</span>.`$Class<span style="color: #800000;">&quot;
}
&quot;</span><span style="color: pink;">@</span>
    <span style="color: #008080; font-weight: bold;">Set-Item</span> <span style="color: #008080; font-style: italic;">-Path</span> <span style="color: #800000;">&quot;function:global:New-$NSObject&quot;</span> <span style="color: #008080; font-style: italic;">-Value</span> <span style="color: #800080;">$function</span> <span style="color: #008080; font-style: italic;">-force</span>
    <span style="color: #008080; font-weight: bold;">Write-Debug</span> <span style="color: #800000;">&quot;Created function:global:New-$NSObject &quot;</span>
    <span style="color: #000000;">&#125;</span>
  <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></td></tr></table></div>

<p>PSMDTAG:FAQ CLR<br />
PSMDTAG:FAQ Namespace<br />
PSMDTAG:FAQ .NET Framework</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.usepowershell.com/2009/04/exploring-the-net-framework-with-powershell-namespaces-part-5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Microsoft TechDays Virtual Event</title>
		<link>http://blog.usepowershell.com/2009/03/microsoft-techdays-virtual-event/</link>
		<comments>http://blog.usepowershell.com/2009/03/microsoft-techdays-virtual-event/#comments</comments>
		<pubDate>Thu, 26 Mar 2009 13:01:27 +0000</pubDate>
		<dc:creator>Steven Murawski</dc:creator>
				<category><![CDATA[.NET Framework]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Events]]></category>
		<category><![CDATA[PowerShell Community]]></category>

		<guid isPermaLink="false">http://blog.usepowershell.com/2009/03/microsoft-techdays-virtual-event/</guid>
		<description><![CDATA[On April 1st, 2009, Microsoft is putting on a free 24 hour virtual event covering developer-related topics. There will be 95 live sessions provided via Live Meeting in the following tracks: Windows Development and Frameworks Windows Mobile Development Office and SharePoint Development Developer Tools, Languages &#38; Practices Web Development &#38; User Experience PowerShell Community’s own [...]]]></description>
			<content:encoded><![CDATA[<p>On April 1st, 2009, Microsoft is putting on a free 24 hour virtual event covering developer-related topics.   <br />There will be 95 live sessions provided via Live Meeting in the following tracks:</p>
<ul>
<li>Windows Development and Frameworks</li>
<li>Windows Mobile Development</li>
<li>Office and SharePoint Development</li>
<li>Developer Tools, Languages &amp; Practices</li>
<li>Web Development &amp; User Experience</li>
</ul>
<p>PowerShell Community’s own <a href="http://marcoshaw.blogspot.com/" target="_blank">Marco Shaw (MVP)</a> will be presenting the <strong>ONLY</strong> PowerShell session:</p>
<blockquote><p>WIN300 Scripting the Microsoft .NET Framework Using Windows PowerShell     <br />Now that PowerShell is part of the Microsoft Common Engineering Criteria, expect to see more and more PowerShell in Microsoft server products. This session looks at how PowerShell can be used to directly access the .NET Framework. Some simple examples are demonstrated, but also more advanced examples of using Windows Presentation Foundation (.NET 3.0) and LINQ (.NET 3.5) are discussed.</p>
</blockquote>
<p>You can find more information about this event <a href="http://www.msfttechdays.com/public/sessions.aspx" target="_blank">here</a> or on <a href="http://marcoshaw.blogspot.com/2009/03/free-event-techdays-defy-all-challenges.html" target="_blank">Marco’s blog</a>.&#160; </p>
<p>I’m looking forward to seeing this presentation.&#160; Hope to “see” you there!&#160; <a href="http://www.msfttechdays.com/Modules/Registration/Submit.aspx" target="_blank">Register now..</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.usepowershell.com/2009/03/microsoft-techdays-virtual-event/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tip: Free Up Some Memory</title>
		<link>http://blog.usepowershell.com/2009/03/tip-free-up-some-memory/</link>
		<comments>http://blog.usepowershell.com/2009/03/tip-free-up-some-memory/#comments</comments>
		<pubDate>Thu, 26 Mar 2009 01:03:02 +0000</pubDate>
		<dc:creator>Steven Murawski</dc:creator>
				<category><![CDATA[.NET Framework]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[Tip]]></category>

		<guid isPermaLink="false">http://blog.usepowershell.com/2009/03/tip-free-up-some-memory/</guid>
		<description><![CDATA[I’m often running too many applications on my workstation, and at least one session of&#160; PowerShell is almost always open.&#160; I’m regularly jumping back to a PowerShell prompt to try something out, query something from my database, or complete a task.&#160; If I don’t clear out the variables that reference objects I’m done with, the [...]]]></description>
			<content:encoded><![CDATA[<p>I’m often running too many applications on my workstation, and at least one session of&#160; <a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/download.mspx" target="_blank">PowerShell</a> is almost always open.&#160; I’m regularly jumping back to a PowerShell prompt to try something out, query something from my database, or complete a task.&#160; </p>
<p>If I don’t clear out the variables that reference objects I’m done with, the amount of memory used by my PowerShell session increases dramatically, which impacts some other applications that I run.&#160; (I know, memory is cheap.. buy more memory.&#160; I’ve got a limited budget and I have to prioritize.)</p>
<p>So I’ve written a couple of functions that can help me clear out the extraneous variables and free up some of that memory being used by PowerShell.</p>
<p>The first function (and I’m open to suggestions on the naming here..), <a href="http://poshcode.org/973" target="_blank">Set-SessionVariableList</a>, reads in all the variable names in the global scope and <a href="http://blog.usepowershell.com/2009/03/tip-sneaky-storage-whats-in-your-appdomain/" target="_blank">saves them to the AppDomain</a> (so I don’t lose them when I clear out variables).&#160; I recommend running this shortly after starting PowerShell or running it from your profile. </p>
<p>Later, when I’m feeling some memory pressure, I can run the second function <a href="http://poshcode.org/973" target="_blank">Remove-NewVariable</a>, which calls Remove-Variable for all variables whose names I did not save in the AppDomain.&#160; This removes the references to the objects they represented.&#160; </p>
<p><strong>Info Overload: Notice that I said that it removed the references to those objects.&#160; Those objects still exist in memory and remain there until the CLR “garbage collects” them, releasing that memory.&#160; The CLR has a process to reclaim that “used” memory when there is a need to reuse it or when it is impacting other performance.</strong></p>
<p>Even if you skipped the previous bold section (which is perfectly acceptable), you might have noticed that when you clear out a variable, your memory usage for PowerShell might remain high for a while.&#160; My function speeds up the natural “garbage collection” process by calling <a href="http://msdn.microsoft.com/en-us/library/system.gc.collect.aspx" target="_blank">[System.GC]::Collect()</a>, forcing the CLR to reclaim that memory.</p>
<p>There are a couple of “helper” functions included, Get-SessionVariableList, which will list out the variable names saved, in case you wanted to see which variables were going to be left and Add-SessionVariable, which adds more values to the current list.&#160; </p>
<p>&#160;</p>
<p> <script type="text/javascript" src="http://PoshCode.org/embed/973"></script>
<p>Feedback and improvements are always welcome!</p>
<p><a href="http://blogs.msdn.com/powershell/archive/2009/03/01/powershell-folksonomy.aspx" target="_blank">PSMDTAG</a>:FAQ Memory</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.usepowershell.com/2009/03/tip-free-up-some-memory/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tip: Sneaky Storage &#8211; What&#8217;s in your AppDomain?</title>
		<link>http://blog.usepowershell.com/2009/03/tip-sneaky-storage-whats-in-your-appdomain/</link>
		<comments>http://blog.usepowershell.com/2009/03/tip-sneaky-storage-whats-in-your-appdomain/#comments</comments>
		<pubDate>Tue, 24 Mar 2009 14:49:54 +0000</pubDate>
		<dc:creator>Steven Murawski</dc:creator>
				<category><![CDATA[.NET Framework]]></category>
		<category><![CDATA[Base Class Libraries]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://blog.usepowershell.com/2009/03/tip-sneaky-storage-whats-in-your-appdomain/</guid>
		<description><![CDATA[Since PowerShell is built on .NET, there is a AppDomain (I’ll go into more detail in a later post) which has a lot of information about the .NET environment (what assemblies are loaded, etc..). One feature that the AppDomain has is to store globally accessible name/value pairs.&#160; Normally, variables in PowerShell should handle most of [...]]]></description>
			<content:encoded><![CDATA[<p>Since PowerShell is built on .NET, there is a <a href="http://msdn.microsoft.com/en-us/library/system.appdomain.aspx" target="_blank">AppDomain</a> (I’ll go into more detail in a later post) which has a lot of information about the .NET environment (what assemblies are loaded, etc..).</p>
<p>One feature that the AppDomain has is to store globally accessible name/value pairs.&#160; Normally, variables in PowerShell should handle most of your “in-process” storage needs, but for the times that they don’t, you have your AppDomain.</p>
<p>To access the AppDomain object, you can use the static property <a href="http://msdn.microsoft.com/en-us/library/system.appdomain.currentdomain.aspx" target="_blank">CurrentDomain</a> on the <a href="http://msdn.microsoft.com/en-us/library/system.appdomain.aspx" target="_blank">System.AppDomain</a> class. </p>
<p><strong>(NOTE: Though I usually refer use the fully qualified namespace, PowerShell does allow you to skip the “System” portion of the namespace.&#160; I’m using the full namespace for clarity on the blog, but when typing on the command line, it is easier to skip that.)</strong></p>
<p>PS C:\&gt; [system.appdomain]::CurrentDomain</p>
<p>To save a name/value pair to your AppDomain, you can use the <a href="http://msdn.microsoft.com/en-us/library/system.appdomain.setdata.aspx" target="_blank">SetData</a> method.</p>
<p>PS C:\&gt; [system.appdomain]::CurrentDomain.SetData(&#8216;ThisIsMyNameOrKey&#8217;, (&#8216;This&#8217;,'Can&#8217;,'Be&#8217;,'Any&#8217;,'Object&#8217;,'Or&#8217;,'Collection&#8217;) )</p>
<p>Any object or collection can be saved in the AppDomain, and you are not limited to just one.</p>
<p>Accessing those values is just as easy, using the <a href="http://msdn.microsoft.com/en-us/library/system.appdomain.getdata.aspx" target="_blank">GetData</a> method.</p>
<p>PS C:\&gt; [system.appdomain]::CurrentDomain.GetData(&#8216;ThisIsMyNameOrKey&#8217;)   <br />This    <br />Can    <br />Be    <br />Any    <br />Object    <br />Or    <br />Collection</p>
<p>And there we have our collection back.</p>
<p><a href="http://blogs.msdn.com/powershell/archive/2009/03/01/powershell-folksonomy.aspx">PSMDTAG</a>:.Net AppDomain</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.usepowershell.com/2009/03/tip-sneaky-storage-whats-in-your-appdomain/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Exploring the .NET Framework with PowerShell – Static Members (Part 4)</title>
		<link>http://blog.usepowershell.com/2009/03/exploring-the-net-framework-with-powershell-static-members-part-4/</link>
		<comments>http://blog.usepowershell.com/2009/03/exploring-the-net-framework-with-powershell-static-members-part-4/#comments</comments>
		<pubDate>Fri, 20 Mar 2009 13:02:54 +0000</pubDate>
		<dc:creator>Steven Murawski</dc:creator>
				<category><![CDATA[.NET Framework]]></category>
		<category><![CDATA[Base Class Libraries]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Introduction]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://blog.usepowershell.com/2009/03/exploring-the-net-framework-with-powershell-static-members-part-4/</guid>
		<description><![CDATA[In our Exploring the .NET Framework series, we’ve covered some terminology, creating instances of objects and calling methods.  In today’s installment, we are going to look at using static members &#8211; methods and properties.  Static methods are methods that a class (or type) make available without needing to create an instance of the class.  Similarly, [...]]]></description>
			<content:encoded><![CDATA[<p>In our <a href="http://blog.usepowershell.com/category/net-framework/introduction/" target="_blank">Exploring the .NET Framework series</a>, we’ve covered some terminology, creating instances of objects and calling methods.  In today’s installment, we are going to look at using static members &#8211; methods and properties.  Static methods are methods that a class (or type) make available without needing to create an instance of the class.  Similarly, static properties are properties that you can access without needing an instance of the class.</p>
<p>Many classes provide static members supply functionality where it doesn’t make sense to need an object. </p>
<p>The <a href="http://msdn.microsoft.com/en-us/library/system.math.aspx" target="_blank">System.Math</a> class contains a couple of static properties, PI and E. </p>
<p>PS C:\scripts\PowerShell&gt; [math]::E<br />
2.71828182845905<br />
PS C:\scripts\PowerShell&gt; [math]::PI<br />
3.14159265358979</p>
<p>Constant values are not the only type of property that you’ll find.  The <a href="http://msdn.microsoft.com/en-us/library/system.appdomain.aspx" target="_blank">System.AppDomain</a> class has a static property, <a href="http://msdn.microsoft.com/en-us/library/system.appdomain.currentdomain.aspx" target="_blank">CurrentDomain</a>, which is an AppDomain instance referring to the current application domain.</p>
<p>PS C:\scripts\PowerShell&gt; [AppDomain]::CurrentDomain.gettype()</p>
<p>IsPublic  IsSerial Name         BaseType<br />
&#8212;&#8212;&#8211;    &#8212;&#8212;&#8211;    &#8212;-            &#8212;&#8212;&#8211;<br />
True     False    AppDomain System.MarshalByRefObject</p>
<p>System.Math also contains a number of static methods that provide a great deal of basic mathematical function.</p>
<p>PS C:\scripts\PowerShell&gt;[Math] | get-member –static –membertype method | select name</p>
<p>Name<br />
&#8212;-<br />
Abs<br />
Acos<br />
Asin<br />
Atan<br />
Atan2<br />
BigMul<br />
Ceiling<br />
Cos<br />
Cosh<br />
DivRem<br />
Equals<br />
Exp<br />
Floor<br />
IEEERemainder<br />
Log<br />
Log10<br />
Max<br />
Min<br />
Pow<br />
ReferenceEquals<br />
Round<br />
Sign<br />
Sin<br />
Sinh<br />
Sqrt<br />
Tan<br />
Tanh<br />
Truncate</p>
<p>I wrote a little helper function to get the static method definitions (<a href="http://poshcode.org/968" target="_blank">Get-StaticMethodDefinition</a>), which you can grab from <a href="http://poshcode.org/" target="_blank">PoshCode.org</a>.</p>
<p>(V2 CTP3 &#8211; We can use the trick of using the method name without parenthesis following to get additional information on each of the methods that we are interested in.)</p>
<p>One type of static method that I would like to highlight is the factory method.  A factory method is a common way of controlling object creation.  At its most basic level, a factory pattern is a method that creates objects of a specified type. </p>
<p>An example of this is the <a href="http://msdn.microsoft.com/en-us/library/system.net.webrequest.aspx" target="_blank">System.Net.WebRequest’s</a> Create method.</p>
<p>PS C:\scripts\PowerShell&gt; $web = [net.webrequest]::create(&#8216;<a href="http://www.google.com">http://www.google.com</a>&#8216;)<br />
PS C:\scripts\PowerShell&gt; $web.gettype()</p>
<p>IsPublic IsSerial Name                                     BaseType<br />
&#8212;&#8212;&#8211; &#8212;&#8212;&#8211; &#8212;-                                     &#8212;&#8212;&#8211;<br />
True     True     HttpWebRequest                           System.Net.WebReq&#8230;</p>
<p>The factory method Create used the argument (‘http://www.google.com’) to determine the type of <a href="http://msdn.microsoft.com/en-us/library/system.net.webrequest.aspx" target="_blank">WebRequest</a> object to create.  In this case, it created an <a href="http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.aspx" target="_blank">HttpWebRequest</a> object, which is a more specialized version of the WebRequest for HTTP requests. </p>
<p>Let’s see how it would respond if we passed the Create method a URI with FTP.</p>
<p>PS C:\scripts\PowerShell&gt; $web = [net.webrequest]::create(&#8216;<a href="ftp://ftp.google.com'">ftp://ftp.google.com&#8217;</a>)<br />
PS C:\scripts\PowerShell&gt; $web.gettype()</p>
<p>IsPublic IsSerial Name                                     BaseType<br />
&#8212;&#8212;&#8211; &#8212;&#8212;&#8211; &#8212;-                                     &#8212;&#8212;&#8211;<br />
True     False    FtpWebRequest                            System.Net.WebReq&#8230;</p>
<p>As we can see, the WebRequest class created an <a href="http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.aspx" target="_blank">FtpWebRequest</a> object.</p>
<p>Factory methods provide developers a way to more flexibly support different operations by allowing the static method to determine which object to return.</p>
<p><strong>UPDATE:  <a href="http://huddledmasses.org/" target="_self">Joel &#8220;Jaykul&#8221; Bennet</a> added a <a href="http://poshcode.org/969" target="_blank">V2 advanced function to convert static methods to functions</a> to PoShCode.org  and pointed out <a href="http://www.nivot.org/2007/08/13/CreatingFunctionsFromANETClasssStaticMethods.aspx" target="_blank">Oisin Grehan&#8217;s blog post about creating functions from static methods (V1 compatible)</a>.</strong></p>
<p>I’ve been really happy to receive some of the feedback (positive and constructive criticism) on this series.  There is a lot of the <a href="http://msdn.microsoft.com/en-us/netframework/default.aspx" target="_blank">.NET Framework</a> to cover, and I’m open to suggestions as to what you would like to know.  Please post a comment on the blog or email me at Steve at UsePowerShell.Com.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.usepowershell.com/2009/03/exploring-the-net-framework-with-powershell-static-members-part-4/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How To Send E-Mail From PowerShell</title>
		<link>http://blog.usepowershell.com/2009/03/how-to-send-e-mail-from-powershell/</link>
		<comments>http://blog.usepowershell.com/2009/03/how-to-send-e-mail-from-powershell/#comments</comments>
		<pubDate>Mon, 02 Mar 2009 15:30:00 +0000</pubDate>
		<dc:creator>Steven Murawski</dc:creator>
				<category><![CDATA[.NET Framework]]></category>
		<category><![CDATA[Base Class Libraries]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[PowerShell Version 1]]></category>

		<guid isPermaLink="false">http://blog.usepowershell.com/?p=60</guid>
		<description><![CDATA[In my Exploring the .NET Framework series, I introduced the System.Net.Mail.MailMessage class.&#160; Being able to create a MailMessage object is all well and good, but if you can’t send it, it’s really not helpful. To send an email from PowerShell using the .NET Framework, you can use the System.Net.Mail.SMTPClient class. First, you need to create [...]]]></description>
			<content:encoded><![CDATA[<p>In my <a href="http://blog.usepowershell.com/category/net-framework/introduction/" target="_blank">Exploring the .NET Framework series</a>, I introduced the <a href="http://msdn.microsoft.com/en-us/library/system.net.mail.mailmessage.aspx#" target="_blank">System.Net.Mail.MailMessage</a> class.&#160; Being able to create a MailMessage object is all well and good, but if you can’t send it, it’s really not helpful.</p>
<p>To send an email from <a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/download.mspx" target="_blank">PowerShell</a> using the .NET Framework, you can use the <a href="http://msdn.microsoft.com/en-us/library/system.net.mail.smtpclient.aspx#" target="_blank">System.Net.Mail.SMTPClient</a> class.</p>
<p>First, you need to create your MailMessage</p>
<p>PS C:\scripts\PowerShell&gt; $message = <a href="http://technet.microsoft.com/en-us/library/d203c4ab-2d57-4103-a04e-d7869d06931e" target="_blank">New-Object</a> System.Net.Mail.MailMessage –ArgumentList <a href="mailto:steve@usepowershell.com">steve@usepowershell.com</a>, <a href="mailto:nobody@adomain.com">nobody@adomain.com</a>, ‘This is a test’, ‘I’m going to send an email via PowerShell’</p>
<p>If you need to add an attachment, you can add one with the <a href="http://msdn.microsoft.com/en-us/library/system.net.mail.attachment.aspx" target="_blank">System.Net.Mail.Attachment</a> class.</p>
<p>To create the attachment, we’ll create an use an overload of the Attachment class that allows us to specify a filename and a MIME type (the MIME types are available in several enumerations:&#160; <a href="http://msdn.microsoft.com/en-us/library/system.net.mime.mediatypenames.application.aspx" target="_blank">System.Net.Mime.MediaTypeNames.Application</a>, <a href="http://msdn.microsoft.com/en-us/library/system.net.mime.mediatypenames.image.aspx" target="_blank">System.Net.Mime.MediaTypeNames.Image</a>, and <a href="http://msdn.microsoft.com/en-us/library/system.net.mime.mediatypenames.text.aspx" target="_blank">System.Net.Mime.MediaTypeNames.Text</a> – I’ve had a bit of trouble accessing those enumerations via PowerShell, but you can specify the name of the enumeration value in a string).</p>
<p>PS C:\scripts\PowerShell&gt; $attachment = <a href="http://technet.microsoft.com/en-us/library/d203c4ab-2d57-4103-a04e-d7869d06931e" target="_blank">New-Object</a> System.Net.Mail.Attachment –ArgumentList &#8216;c:\docs\test.xls’, ‘Application/Octet’</p>
<p>PS C:\scripts\PowerShell&gt; $message.Attachments.Add($attachment)</p>
<p>After we have our email and optional attachment, we’ll create the SMTP client and have it configured to use the SMTP server of our choice.</p>
<p>The constructor of the SMTPClient class that we will use is</p>
<p>SmtpClient(    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; String host,     <br />)</p>
<p>PS C:\scripts\PowerShell&gt; $smtp = New-Object System.Net.Mail.SMTPClient –ArgumentList 10.10.10.15</p>
<p>All that is left is sending our email..</p>
<p>PS C:\scripts\PowerShell&gt; $smtp.Send($message)</p>
<p>Have fun!</p>
<p>NOTE:</p>
<p>There is a shortcut to creating the MailMessage object like we did.. there is an overload of Send where you can pass in four strings (from, to, subject, and message).&#160; The SMTPClient handles the creation of the MailMessage in the background.</p>
<p>A faster method would be</p>
<p>PS C:\scripts\PowerShell&gt; $smtp = New-Object System.Net.Mail.SMTPClient –ArgumentList 10.10.10.15</p>
<p>PS C:\scripts\PowerShell&gt; $smtp.Send(‘<a href="mailto:steve@usepowershell.com">steve@usepowershell.com</a>’, ‘<a href="mailto:nobody@adomain.com">nobody@adomain.com</a>’, ‘This is a test’, ‘I’m going to send an email via PowerShell’)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.usepowershell.com/2009/03/how-to-send-e-mail-from-powershell/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Exploring the .NET Framework with PowerShell &#8211; Constructors (Part 3)</title>
		<link>http://blog.usepowershell.com/2009/03/exploring-the-net-framework-with-powershell-constructors-part-3/</link>
		<comments>http://blog.usepowershell.com/2009/03/exploring-the-net-framework-with-powershell-constructors-part-3/#comments</comments>
		<pubDate>Mon, 02 Mar 2009 13:30:00 +0000</pubDate>
		<dc:creator>Steven Murawski</dc:creator>
				<category><![CDATA[.NET Framework]]></category>
		<category><![CDATA[Base Class Libraries]]></category>
		<category><![CDATA[Introduction]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[PowerShell Version 1]]></category>

		<guid isPermaLink="false">http://blog.usepowershell.com/?p=9</guid>
		<description><![CDATA[In part 2(a &#38; b) of this series, we talked about methods and looked at ways to view their overloads, or ways to call them.&#160; We also looked at the objects returned from a method call.&#160; In this post, we are going to explore a special kind of method called the constructor. A constructor is [...]]]></description>
			<content:encoded><![CDATA[<p>In part 2(<a href="http://blog.usepowershell.com/2009/02/exploring-the-net-framework-with-powershell-calling-a-method-part-2a/" target="_blank">a</a> &amp; <a href="http://blog.usepowershell.com/2009/02/exploring-the-net-framework-with-powershell-calling-a-method-part-2b/" target="_blank">b</a>) of this series, we talked about methods and looked at ways to view their overloads, or ways to call them.&#160; We also looked at the objects returned from a method call.&#160; In this post, we are going to explore a special kind of method called the constructor.</p>
<p>A constructor is a method whose job is to create the object that you want to work with.&#160; When I created the Ping object</p>
<p>PS C:\scripts\PowerShell&gt; $ping = New-Object System.Net.NetworkInformation.Ping</p>
<p>the <a href="http://technet.microsoft.com/en-us/library/d203c4ab-2d57-4103-a04e-d7869d06931e" target="_blank">New-Object</a> cmdlet calls the <a href="http://msdn.microsoft.com/en-us/library/system.net.networkinformation.ping.ping.aspx" target="_blank">constructor for Ping</a>.</p>
<p>Like other methods, constructors can require parameters and can have multiple overloads.&#160; </p>
<p>Let’s look at <a href="http://msdn.microsoft.com/en-us/library/system.net.mail.mailmessage.aspx#" target="_blank">System.Net.Mail.MailMessage</a>, which is a object that represents an email message.</p>
<p>The <a href="http://msdn.microsoft.com/en-us/library/system.net.mail.mailmessage.mailmessage.aspx" target="_blank">MailMessage constructor</a> contains several overloads.&#160; The first method listed is MailMessage(), which is the default constructor.&#160; This method does not require any arguments and returns an empty MailMessage object.&#160; In <a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/download.mspx" target="_blank">PowerShell</a>, we would call this method via <a href="http://technet.microsoft.com/en-us/library/d203c4ab-2d57-4103-a04e-d7869d06931e" target="_blank">New-Object</a>, just like with Ping class.</p>
<p>MailMessage()</p>
<p> PS C:\scripts\PowerShell&gt; $message = New-Object System.Net.Mail.MailMessage</p>
<p>The first overload requires two <a href="http://msdn.microsoft.com/en-us/library/system.net.mail.mailaddress.aspx" target="_blank">MailAddress</a> objects, the first of which is the “from” address and the second is the “to” address.&#160; </p>
<p>MailMessage(   <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; MailAddress from,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; MailAddress to,    <br />)</p>
<p>Creating an object in PowerShell from a constructor that requires parameters can be done in two ways.&#160; The first is to use the method call notation.</p>
<p> PS C:\scripts\PowerShell&gt; $message = New-Object System.Net.Mail.MailMessage($MailFrom, $MailTo)</p>
<p>The second is to use the ArgumentList parameter.</p>
<p> PS C:\scripts\PowerShell&gt; $message = New-Object System.Net.Mail.MailMessage –ArgumentList $MailFrom, $MailTo</p>
<p>If you happen to have <a href="http://msdn.microsoft.com/en-us/library/system.net.mail.mailaddress.aspx" target="_blank">MailAddress</a> objects floating around, this might work for you.&#160; A more common scenario would be to use the next overload, which takes two strings.</p>
<p>MailMessage(   <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; String from,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; String to,    <br />)</p>
<p>This overload requires two strings, one for the “to” and one for the “from” address.&#160; </p>
<p>The final overload for MailMessage is</p>
<p>MailMessage(   <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; String from,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; String to,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; String subject,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; String body,    <br />)</p>
<p>This overload allows you to pass in four strings and get back basic MailMessage object that is ready to be sent.</p>
<p>Wouldn’t it be great to have a function, where we could provide a type name and get a listing of all the constructors, right from the command line (not needing to go to the MSDN documentation every time).&#160; Jeffrey Snover has beaten me to the punch and provided a function to find the constructors, appropriately called <a href="http://blogs.msdn.com/powershell/archive/2008/09/01/get-constructor-fun.aspx" target="_blank">Get-Constructor</a>.&#160; Add that function to the your toolbox, and exploring the .NET Framework becomes a lot easier.</p>
<p>Next up, we’ll look at static methods.&#160; Static methods are methods that can be called without having to create a instance of an object.</p>
<p>One particular type of static method that we’ll dig in to is the factory method, which is another way to create instances of objects.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.usepowershell.com/2009/03/exploring-the-net-framework-with-powershell-constructors-part-3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Exploring the .NET Framework with PowerShell &#8211; Calling a Method (Part 2b)</title>
		<link>http://blog.usepowershell.com/2009/02/exploring-the-net-framework-with-powershell-calling-a-method-part-2b/</link>
		<comments>http://blog.usepowershell.com/2009/02/exploring-the-net-framework-with-powershell-calling-a-method-part-2b/#comments</comments>
		<pubDate>Thu, 19 Feb 2009 14:00:00 +0000</pubDate>
		<dc:creator>Steven Murawski</dc:creator>
				<category><![CDATA[.NET Framework]]></category>
		<category><![CDATA[Base Class Libraries]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Introduction]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://blog.usepowershell.com/?p=42</guid>
		<description><![CDATA[Continuing from where I left off last week, we were created an instance of the System.Net.NetworkInformation.Ping class and looked at the different ways (overloads) that we can call the Send method.&#160; Now that we’ve seen how we can create Ping objects, let’s take advantage of options for creating some custom ping packets and examine the [...]]]></description>
			<content:encoded><![CDATA[<p>Continuing from where <a href="http://blog.usepowershell.com/2009/02/exploring-the-net-framework-with-powershell-calling-a-method-part-2a/" target="_blank">I left off last week</a>, we were created an instance of the <a href="http://msdn.microsoft.com/en-us/library/system.net.networkinformation.ping.aspx" target="_blank">System.Net.NetworkInformation.Ping</a> class and looked at the different ways (overloads) that we can call the Send method.&#160; Now that we’ve seen how we can create Ping objects, let’s take advantage of options for creating some custom ping packets and examine the return object.</p>
<p>PS C:\&gt; $encoder = new-object System.Text.ASCIIEncoding</p>
<p>PS C:\&gt; $bytes = $encoder.Getbytes(&#8216;Hello From Steve&#8217;)</p>
<p>PS C:\&gt; $response = $ping.Send(&#8216;google.com&#8217;, 100, $bytes)</p>
<p>Let’s take a look at the response we get back.</p>
<p>PS C:\&gt; $response | Get-Member</p>
<p>&#160;&#160; TypeName: System.Net.NetworkInformation.PingReply</p>
<p>Name&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; MemberType&#160;&#160;&#160;&#160; Definition    <br />&#8212;-&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &#8212;&#8212;&#8212;-&#160;&#160;&#160;&#160; &#8212;&#8212;&#8212;-     <br />Equals&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Boolean Equals(Object obj)     <br />GetHashCode&#160;&#160;&#160;&#160;&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Int32 GetHashCode()     <br />GetType&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Type GetType()     <br />get_Address&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Net.IPAddress get_Address()     <br />get_Buffer&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Byte[] get_Buffer()     <br />get_Options&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Net.NetworkInformation.PingOptions&#8230;     <br />get_RoundtripTime Method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Int64 get_RoundtripTime()     <br />get_Status&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.Net.NetworkInformation.IPStatus ge&#8230;     <br />ToString&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.String ToString()     <br />Address&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Property&#160;&#160;&#160;&#160;&#160;&#160; System.Net.IPAddress Address {get;}     <br />Buffer&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Property&#160;&#160;&#160;&#160;&#160;&#160; System.Byte[] Buffer {get;}     <br />Options&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Property&#160;&#160;&#160;&#160;&#160;&#160; System.Net.NetworkInformation.PingOptions&#8230;     <br />RoundtripTime&#160;&#160;&#160;&#160;&#160;&#160; Property&#160;&#160;&#160;&#160;&#160;&#160; System.Int64 RoundtripTime {get;}     <br />Status&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Property&#160;&#160;&#160;&#160;&#160;&#160; System.Net.NetworkInformation.IPStatus St&#8230;     <br />BufferSize&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ScriptProperty System.Object BufferSize {get=$this.Buffe&#8230;     <br />OptionsString&#160;&#160;&#160;&#160;&#160;&#160;&#160; ScriptProperty System.Object OptionsString {get=&#8217;TTL={0}&#8230;</p>
<p>Get-Member shows us that this is a <a href="http://msdn.microsoft.com/en-us/library/system.net.networkinformation.pingreply.aspx" target="_blank">PingReply</a> object in the <a href="http://msdn.microsoft.com/en-us/library/system.net.networkinformation.aspx" target="_blank">System.Net.NetworkInformation</a> namespace.</p>
<p>Looking at the <a href="http://msdn.microsoft.com/en-us/library/system.net.networkinformation.pingreply.aspx" target="_blank">PingReply</a> object that was returned, we have several methods that look strangely similar to the properties, but with a “get_” prefixed to it.&#160; When you see a method that matches a Property, but has “get_” or “set_”, that is a method exposed by the <a href="http://msdn.microsoft.com/en-us/netframework/default.aspx" target="_blank">.NET Framework</a> that provides the functionality for the properties.&#160; When you access the Buffer property, you are actually calling the get_Buffer method.&#160; Properties are, for the most part, easier to work with and you can effectively ignore those methods.&#160; Properties also contain a clue in their description, if you look at the end of the Buffer property’s description, you see “{get;}” which indicates that there is a way to retrieve that property.&#160; Properties can also show “{set;}” which indicates that you can update that property.</p>
<p>In <a href="http://www.microsoft.com/DOWNLOADS/details.aspx?FamilyID=c913aeab-d7b4-4bb1-a958-ee6d7fe307bc&amp;displaylang=en" target="_blank">PowerShell V2 CTP3</a> those “getters” and “setters” (as those methods are commonly called) are hidden by default.&#160; If you are running CTP3 and want to see the “getters” and “setters”, you can call Get-Member with the Force parameter.</p>
<p>PS C:\&gt; $response | Get-Member –Force</p>
<p>Back to the properties of our return object.&#160; The properties names are pretty self-explanatory, but to confirm we got back the “special” packet we crafted, let’s take a look at the Buffer property and convert that back to text.</p>
<p>PS C:\&gt; $encoder.GetString($response.buffer)    <br />Hello From Steve</p>
<p>Now for the meat of the response, the RoundtripTime and Status.&#160; I commonly use the Roundtrip time to watch for latency on my network, and since it is exposed so nicely, it is easy to log.</p>
<p>PS C:\&gt; $response.RoundtripTime    <br />74</p>
<p>And of course, we are interested in the Status.</p>
<p>PS C:\&gt; $response.Status    <br />Success</p>
<p>Now, we can see from the Get-Member return above, that Status is not just a string that says, “Success”, it is a <a href="http://msdn.microsoft.com/en-us/library/system.net.networkinformation.ipstatus.aspx" target="_blank">IPStatus</a> enumeration (more on enumerations coming up, but long story short, there are a number of predefined values that an <a href="http://msdn.microsoft.com/en-us/library/system.net.networkinformation.ipstatus.aspx" target="_blank">IPStatus</a> object can hold)(also found in the <a href="http://msdn.microsoft.com/en-us/library/system.net.networkinformation.aspx" target="_blank">System.Net.NetworkInformation</a> namespace).&#160; </p>
<p>I’m normally checking the IPStatus for a Success value like</p>
<p>PS C:\&gt; $success = [System.Net.NetworkInformation.IPStatus]::Success</p>
<p>PS C:\&gt; $response.status -eq $success    <br />True</p>
<p>I could compare the string results, but then I’m stepping back to parsing text results.&#160; By using the <a href="http://msdn.microsoft.com/en-us/library/system.net.networkinformation.ipstatus.aspx" target="_blank">IPStatus</a> enumeration values, I can get be reasonably sure that my value are correct and I don’t have any text matching issues.</p>
<p>In the next post in this series, we’ll take a look at a special type of method, the constructor.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.usepowershell.com/2009/02/exploring-the-net-framework-with-powershell-calling-a-method-part-2b/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Adding Custom Properties to Functions</title>
		<link>http://blog.usepowershell.com/2009/02/adding-custom-properties-to-functions/</link>
		<comments>http://blog.usepowershell.com/2009/02/adding-custom-properties-to-functions/#comments</comments>
		<pubDate>Sat, 14 Feb 2009 02:24:26 +0000</pubDate>
		<dc:creator>Steven Murawski</dc:creator>
				<category><![CDATA[.NET Framework]]></category>
		<category><![CDATA[PowerShell]]></category>
		<category><![CDATA[PowerShell Version 1]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[adaptive type system]]></category>
		<category><![CDATA[ps1xml]]></category>
		<category><![CDATA[type data]]></category>

		<guid isPermaLink="false">http://blog.usepowershell.com/2009/02/adding-custom-properties-to-functions/</guid>
		<description><![CDATA[A question was asked on StackOverflow regarding how to add properties to a function, and then be able to retain that custom property when recalling that function from the function Provider.&#160;&#160; I’m not going to copy my answer here, but I do want to throw out a possible work around for this issue.&#160; (It has [...]]]></description>
			<content:encoded><![CDATA[<p>A q<a href="http://stackoverflow.com/questions/544804/powershell-how-do-you-add-a-property-to-a-function-object-on-the-psdrive-functio" target="_blank">uestion</a> was asked on <a href="http://stackoverflow.com/" target="_blank">StackOverflow</a> regarding how to add properties to a function, and then be able to retain that custom property when recalling that function from the function Provider.&#160;&#160; I’m not going to copy <a href="http://stackoverflow.com/questions/544804/powershell-how-do-you-add-a-property-to-a-function-object-on-the-psdrive-functio/546107#546107" target="_blank">my answer</a> here, but I do want to throw out a possible work around for this issue.&#160; </p>
<p>(It has been bugging me and I can’t really concentrate on my other tasks, so I need to get this out of the way.)</p>
<p>One suggestion I had was to create a type extension that had the property he was adding, but he was more interested in tagging specific functions, not all of them.</p>
<p>So, I’ve written a couple of little ScriptProperties to save and restore NoteProperties which have been added to FunctionInfo objects.&#160; I’ve added these to a PS1XML.</p>
<div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, &#39;Courier New&#39;, courier, monospace; background-color: #f4f4f4">
<div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none">
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   1:</span> &lt;?xml version=<span style="color: #006080">&quot;1.0&quot;</span> encoding=<span style="color: #006080">&quot;utf-8&quot;</span> ?&gt; </pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   2:</span> &lt;Types&gt; </pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   3:</span>     &lt;Type&gt; </pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   4:</span>         &lt;Name&gt;System.Management.Automation.FunctionInfo&lt;/Name&gt; </pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   5:</span>         &lt;Members&gt; </pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   6:</span>             &lt;ScriptMethod&gt; </pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   7:</span>                 &lt;Name&gt;SaveMetadata&lt;/Name&gt; </pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">   8:</span>                 &lt;Script&gt; </pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">   9:</span> $DefaultProperties = <span style="color: #006080">'PSPath'</span>, <span style="color: #006080">'PSDrive'</span>, <span style="color: #006080">'PSProvider'</span>, <span style="color: #006080">'PSIsContainer'</span></pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  10:</span> $SaveDirectory = Split-Path $profile</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  11:</span> $File = Join-Path $SaveDirectory <span style="color: #006080">&quot;$($this.Name).xml&quot;</span></pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  12:</span> $this.PSObject.Properties | Where-Object {$DefaultProperties -notcontains $_.Name -and $_.MemberType <span style="color: #cc6633">-like</span> <span style="color: #006080">'NoteProperty'</span>} | Export-Clixml -Path $file</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  13:</span>                 &lt;/Script&gt; </pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  14:</span>             &lt;/ScriptMethod&gt;</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  15:</span>             &lt;ScriptMethod&gt; </pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  16:</span>                 &lt;Name&gt;LoadMetadata&lt;/Name&gt; </pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  17:</span>                 &lt;Script&gt; </pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  18:</span> $SaveDirectory = split-path $profile</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  19:</span> $PathToCustomProp = Join-Path $SaveDirectory <span style="color: #006080">&quot;$($this.name).xml&quot;</span></pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  20:</span> <span style="color: #0000ff">if</span> (Test-Path $PathToCustomProp)</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  21:</span> {</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  22:</span>     <span style="color: #0000ff">foreach</span> ($Property <span style="color: #0000ff">in</span> Import-Clixml -Path $PathToCustomProp)</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  23:</span>     {</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  24:</span>         Add-Member -InputObject $this -MemberType NoteProperty -Name $Property.Name -Value $Property.Value</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  25:</span>     }</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  26:</span> }</pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  27:</span>                 &lt;/Script&gt; </pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  28:</span>             &lt;/ScriptMethod&gt; </pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  29:</span>         &lt;/Members&gt; </pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"><span style="color: #606060">  30:</span>     &lt;/Type&gt; </pre>
<pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, &#39;Courier New&#39;, courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"><span style="color: #606060">  31:</span> &lt;/Types&gt; </pre>
</p></div>
</div>
<p>After saving this file as a PS1XML file, you can call <a href="http://technet.microsoft.com/en-us/library/dd315362.aspx" target="_blank">Update-TypeData</a> –Prepend path\to\thefile.ps1xml, and every FunctionInfo object will have two script properties – SaveMetadata and LoadMetadata.&#160; As I’ve configured it, the data will be saved to the user’s profile directory and under a filename that matches the function name.&#160; So, you can add NoteProperties to your heart’s desire and save and recall them as needed.&#160; </p>
<p>I don’t have a direct application for this, and it can probably be cleaned up or done more efficiently, but I had to work through the problem.&#160; I’d love to hear your feedback!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.usepowershell.com/2009/02/adding-custom-properties-to-functions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Exploring the .NET Framework with PowerShell &#8211; Calling a Method (Part 2a)</title>
		<link>http://blog.usepowershell.com/2009/02/exploring-the-net-framework-with-powershell-calling-a-method-part-2a/</link>
		<comments>http://blog.usepowershell.com/2009/02/exploring-the-net-framework-with-powershell-calling-a-method-part-2a/#comments</comments>
		<pubDate>Thu, 12 Feb 2009 04:06:38 +0000</pubDate>
		<dc:creator>Steven Murawski</dc:creator>
				<category><![CDATA[.NET Framework]]></category>
		<category><![CDATA[Base Class Libraries]]></category>
		<category><![CDATA[Introduction]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://blog.usepowershell.com/?p=38</guid>
		<description><![CDATA[Last week, I defined a number of terms that we’ll be exposed to as we delve into how and why PowerShell is an object oriented shell and how to use it to explore .NET Framework which it is built upon. Now, let’s take a look at how some of these terms surface themselves in PowerShell. [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.usepowershell.com/2009/02/exploring-the-net-framework-with-powershell-terminology-part-1/" target="_blank">Last week, I defined a number of terms</a> that we’ll be exposed to as we delve into how and why <a href="http://www.microsoft.com/windowsserver2003/technologies/management/powershell/download.mspx" target="_blank">PowerShell</a> is an object oriented shell and how to use it to explore .NET Framework which it is built upon.</p>
<p>Now, let’s take a look at how some of these terms surface themselves in PowerShell.</p>
<p>One of the most common tasks you might encounter is needing to ping a computer.  There is ping.exe, which works and has been a common guest in my console sessions for years.  You can also get ping information via WMI which provides you with some interesting information.</p>
<p>PS C:\scripts\PowerShell&gt; Get-WmiObject Win32_PingStatus -filter &#8220;Address=&#8217;google.com&#8217;&#8221;</p>
<p>My preference is to use a class from the .NET Framework called <a href="http://msdn.microsoft.com/en-us/library/system.net.networkinformation.ping.aspx" target="_blank">Ping</a>.  <a href="http://msdn.microsoft.com/en-us/library/system.net.networkinformation.ping.aspx" target="_blank">Ping</a> lives in the <a href="http://msdn.microsoft.com/en-us/library/system.net.networkinformation.aspx" target="_blank">System.Net.NetworkInformation</a> namespace.</p>
<p>To access this in PowerShell, I’ll create an instance of the class and refer to it with a variable, $ping.</p>
<p>PS C:\scripts\PowerShell&gt; $ping = New-Object System.Net.NetworkInformation.Ping</p>
<p>By typing the method name without the parenthesis immediately after it, PowerShell will give us information about the method.</p>
<p>PS C:\scripts\PowerShell&gt; $ping.send</p>
<p>MemberType          : Method<br />
OverloadDefinitions : {System.Net.NetworkInformation.PingReply Send(String ho<br />
                      stNameOrAddress), System.Net.NetworkInformation.PingRep<br />
                      ly Send(String hostNameOrAddress, Int32 timeout), Syste<br />
                      m.Net.NetworkInformation.PingReply Send(IPAddress addre<br />
                      ss), System.Net.NetworkInformation.PingReply Send(IPAdd<br />
                      ress address, Int32 timeout)&#8230;}<br />
TypeNameOfValue     : System.Management.Automation.PSMethod<br />
Value               : System.Net.NetworkInformation.PingReply Send(String hos<br />
                      tNameOrAddress), System.Net.NetworkInformation.PingRepl<br />
                      y Send(String hostNameOrAddress, Int32 timeout), System<br />
                      .Net.NetworkInformation.PingReply Send(IPAddress addres<br />
                      s), System.Net.NetworkInformation.PingReply Send(IPAddr<br />
                      ess address, Int32 timeout), System.Net.NetworkInformat<br />
                      ion.PingReply Send(String hostNameOrAddress, Int32 time<br />
                      out, Byte[] buffer), System.Net.NetworkInformation.Ping<br />
                      Reply Send(IPAddress address, Int32 timeout, Byte[] buf<br />
                      fer), System.Net.NetworkInformation.PingReply Send(Stri<br />
                      ng hostNameOrAddress, Int32 timeout, Byte[] buffer, Pin<br />
                      gOptions options), System.Net.NetworkInformation.PingRe<br />
                      ply Send(IPAddress address, Int32 timeout, Byte[] buffe<br />
                      r, PingOptions options)<br />
Name                : Send<br />
IsInstance          : True</p>
<p>What I am most interested in is the Overload Definitions, which is the explanation of how I can use this method.</p>
<p>PS C:\scripts\PowerShell&gt; $ping.send.overloaddefinitions</p>
<p>System.Net.NetworkInformation.PingReply Send(String hostNameOrAddress)<br />
System.Net.NetworkInformation.PingReply Send(String hostNameOrAddress, Int32 timeout)<br />
System.Net.NetworkInformation.PingReply Send(IPAddress address)<br />
System.Net.NetworkInformation.PingReply Send(IPAddress address, Int32 timeout)<br />
System.Net.NetworkInformation.PingReply Send(String hostNameOrAddress, Int32 timeout, Byte[] buffer)<br />
System.Net.NetworkInformation.PingReply Send(IPAddress address, Int32 timeout, Byte[] buffer)<br />
System.Net.NetworkInformation.PingReply Send(String hostNameOrAddress, Int32 timeout, Byte[] buffer, PingOptions options)<br />
System.Net.NetworkInformation.PingReply Send(IPAddress address, Int32 timeout, Byte[] buffer, PingOptions options)</p>
<p>As we can see from the above output $ping.<a href="http://msdn.microsoft.com/en-us/library/system.net.networkinformation.ping.send.aspx" target="_blank">Send</a> has several different ways that we can call it and it also shows the object that we will get in return, an object of the type <a href="http://msdn.microsoft.com/en-us/library/system.net.networkinformation.pingreply.aspx" target="_blank">System.Net.NetworkInformation.PingReply</a>.</p>
<p>The first overload for $ping.<a href="http://msdn.microsoft.com/en-us/library/system.net.networkinformation.ping.send.aspx" target="_blank">Send</a> is to supply it an object of the type <a href="http://msdn.microsoft.com/en-us/library/system.string.aspx" target="_blank">String</a> (remember, in PowerShell, even text is an object) which represents the hostname or IP address of the host we wish to ping.</p>
<p>PS C:\scripts\PowerShell&gt; $ping.send(‘google.com’)</p>
<p>Status        : Success<br />
Address       : 74.125.45.100<br />
RoundtripTime : 29 ms<br />
BufferSize    : 32<br />
Options       : TTL=243, DontFragment=False</p>
<p>Here, we called $ping.<a href="http://msdn.microsoft.com/en-us/library/system.net.networkinformation.ping.send.aspx" target="_blank">Send</a> with a argument of the String ‘google.com’ and received back an object of the type PingReply.  We can see the textual representation of it’s properties.  In my next post, we’ll dig into the return object a bit more and see how we can use its properties to our advantage.</p>
<p>We still have a number of other ways that we can call $ping.<a href="http://msdn.microsoft.com/en-us/library/system.net.networkinformation.ping.send.aspx" target="_blank">Send</a>.  Our second option is to provide a <a href="http://msdn.microsoft.com/en-us/library/system.string.aspx" target="_blank">String</a> describing the hostname or IP address (as before), but also allows us to specify a timeout by providing an <a href="http://msdn.microsoft.com/en-us/library/system.int32.aspx" target="_blank">Int32</a>.  (Just a quick note, if you specify a really low timeout value, the reply still may be received.  It is more of an option to provide a longer than normal, five seconds, timeout period.)</p>
<p>We also see overloads that take an object of the <a href="http://msdn.microsoft.com/en-us/library/system.net.ipaddress.aspx" target="_blank">IPAddress</a> type to describe the target of the Ping.</p>
<p>Now, things get a bit more interesting.  The next argument we see is of the type <a href="http://msdn.microsoft.com/en-us/library/system.byte(VS.80).aspx" target="_blank">Byte</a>[], which means an <a href="http://msdn.microsoft.com/en-us/library/system.array.aspx" target="_blank">Array</a> of <a href="http://msdn.microsoft.com/en-us/library/system.byte(VS.80).aspx" target="_blank">Byte</a> objects.  The quick explanation of an <a href="http://msdn.microsoft.com/en-us/library/system.array.aspx" target="_blank">Array</a> is a collection of objects (not 100 percent accurate, but sufficient for right now).  This allows us to specify exactly what data will be sent with the ICMP echo message.</p>
<p>The final argument is to supply an object of the <a href="http://msdn.microsoft.com/en-us/library/system.net.networkinformation.pingoptions.aspx" target="_blank">PingOptions</a> type.  This allows us to specify an <a href="http://msdn.microsoft.com/en-us/library/system.int32.aspx" target="_blank">Int32</a> as the TTL (Time To Live) and a <a href="http://msdn.microsoft.com/en-us/library/system.boolean.aspx" target="_blank">Boolean</a> as Don’t Fragment option.</p>
<p>I’m starting to run a bit long here, so I’m going to continue walking through this example in my next post.  We’ll create an object of type <a href="http://msdn.microsoft.com/en-us/library/system.net.networkinformation.ping.aspx" target="_blank">Ping</a> with some custom options and then dig in to the object that is returned.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.usepowershell.com/2009/02/exploring-the-net-framework-with-powershell-calling-a-method-part-2a/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Exploring the .NET Framework With PowerShell &#8211; Terminology (Part 1)</title>
		<link>http://blog.usepowershell.com/2009/02/exploring-the-net-framework-with-powershell-terminology-part-1/</link>
		<comments>http://blog.usepowershell.com/2009/02/exploring-the-net-framework-with-powershell-terminology-part-1/#comments</comments>
		<pubDate>Wed, 04 Feb 2009 18:34:08 +0000</pubDate>
		<dc:creator>Steven Murawski</dc:creator>
				<category><![CDATA[.NET Framework]]></category>
		<category><![CDATA[Base Class Libraries]]></category>
		<category><![CDATA[Introduction]]></category>
		<category><![CDATA[PowerShell]]></category>

		<guid isPermaLink="false">http://blog.usepowershell.com/?p=12</guid>
		<description><![CDATA[PowerShell opens up the .NET Framework for a large new group of consumers, IT Pro’s (or systems administrators).  Microsoft developers have been working for years with the .NET Framework and now that rich sea of resources is available from our command line. One of the first hurdles that many IT Pro’s come across when trying [...]]]></description>
			<content:encoded><![CDATA[<p>PowerShell opens up the <a href="http://msdn.microsoft.com/en-us/netframework/default.aspx" target="_blank">.NET Framework</a> for a large new group of consumers, IT Pro’s (or systems administrators).  Microsoft developers have been working for years with the .NET Framework and now that rich sea of resources is available from our command line.</p>
<p>One of the first hurdles that many IT Pro’s come across when trying to see where the <a href="http://msdn.microsoft.com/en-us/netframework/default.aspx" target="_blank">.NET Framework</a> fits into their workflow is the terminology. </p>
<p>Before we start digging into the guts of the <a href="http://msdn.microsoft.com/en-us/netframework/default.aspx" target="_blank">.NET Framework</a>, let’s cover some definitions:</p>
<ul>
<li><strong>.NET Framework</strong> – The .NET Framework is a software framework that contains the Common Language Runtime and  Base Class Libraries that provide much of the functionality.  There are several versions of the .NET Framework.  PowerShell is compatible with versions 2.0, 3.0, and 3.5. </li>
<li><strong>Common Language Runtime</strong> (<strong>CLR</strong>) – The Common Language Runtime is the execution environment for .NET applications.  The CLR provides memory management, exception handling, thread management, and security infrastructure.  The CLR is the engine that runs .NET applications.</li>
<li><strong>Base Class Libraries</strong> (<strong>BCL</strong>) – The Base Class Libraries are sets of common functions accessible by any .NET language, including PowerShell.  The BCL is organized into namespaces based on functionality.  For example, the Webclient class is in the System.Net namespace.  The BCL includes functions for working with files, networking, database interaction, graphics, and much more.</li>
<li><strong>Namespace</strong> – A namespace allows CLR functions to be organized and distinguished.  Using a namespace helps prevent naming conflicts without having to have extra long names.  For example, the class System.Net.NetworkInformation.Ping is in the System.Net.NetworkInformation namespace.</li>
<li><strong>Class</strong> – A class is an abstract definition of some functionality.  The class is the definition that the CLR uses when objects are created.  Classes are also referred to as <strong>Types</strong>.  Classes can also have static methods, which are functions that can be used without having to create an instance of the class.</li>
<li><strong>Object</strong> – An object is the <strong>instance</strong> of a class.  An object is a distinct creation in memory that follows the blueprint described in the class.  For example, System.Net.WebClient is a class.  To create an instance of that class in PowerShell, I would: $webclient = New-Object System.Net.WebClient.  The result would be an object of the type System.Net.Webclient which is pointed to by the variable $webclient.</li>
<li><strong>Property</strong> – A property is data that is associated with an object or class.  Properties themselves are objects.  In our example, the System.Net.Webclient object referred to by $webclient has a property Credentials, which is an object of the type System.Net.NetworkCredentials.</li>
<li><strong>Method</strong> – Methods are actions that the object (or type in the case of static methods) can perform.  Methods can have a return type and can require different sets of parameters, allowing you different ways to call them.</li>
<li><strong>Event</strong> – Events are notices that an object can expose, allowing others to run code in response to a change of state of some sort.</li>
<li><strong>Exception</strong> – Exceptions are the error handling mechanism in the CLR.  Exceptions are strongly typed, so you can handle expected errors in your code differently depending on the problem.</li>
</ul>
<p>Now that we’ve got some definitions covered, we’ll start using PowerShell to expose the capabilities that the framework provides us and dig further into these definitions.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.usepowershell.com/2009/02/exploring-the-net-framework-with-powershell-terminology-part-1/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
