Monday, February 21, 2011

Get the most recently written file out of a network share directory with PowerShell

Today’s task is to copy a database backup off of a network share and restore it locally.  So to start we’re copying from a network share to the local host.
$dbName = “MyDBName”
$RemotePath = "\\MyServer\Backup$\" + $dbName + "\"
That puts $RemotePath at a point where I have a variable with the folder that I want. Now test that it works and I have connectivity with a Get-ChildItem
Get-ChildItem $RemotePath
I received results back, so lets filter that down to 7zipped files.
Get-ChildItem $RemotePath –filter “*.7z”
This is good, but I should probably account for if someone decides they want to hide the backup files or something silly like that.
Get-ChildItem $RemotePath –force –filter “*.7z”
That all works, now to sort those files by LastWriteTime
(Thanks StackOverflow for this handy sort)
Get-ChildItem $RemotePath –force –filter “*.7z” | sort @{expression={$_.LastWriteTime}; Descending=$true}
That sorted the list fine, now to select just that last one and only its name.
Get-ChildItem $RemotePath –force –filter “*.7z” | sort @{expression={$_.LastWriteTime}; Descending=$true} | select Name -first 1
And wrapped into a function
function GetLastItem()
{
    param([string]$RemotePath)
    $returnString = Get-ChildItem $RemotePath -force -filter "*.7z" | sort @{expression={$_.LastWriteTime}; Descending=$true} | select Name -first 1
    return $returnString.Name
}
So to use this
$filename = GetLastItem $RemotePath
$RemoteFile = $RemotePath + $filename

Wednesday, February 9, 2011

EPiServer Event Cache Invalidation in a Multi-Server Environment

When multiple servers are setup in EPiServer CMS for load balancing that share a SQL Server backend one common issue is making certain that change from the admin on any server will invalidate the correct cache objects on all servers.

This is all setup very easily within web.config and can be tested quite easily.

I’m not going to go through and explain the full scope of what is going on to accomplish this, but you should know it uses the UDP protocol, multicasting, and Microsoft WCF.  For more information you can visit:

The EPiServer Tech-Note on Configuration

Relevant web.config Sections:

   1: <system.servicemodel>
   2:     <client>
   3:         <endpoint bindingconfiguration="RemoteEventsBinding"
   4:             name="RemoteEventServiceClientEndPoint" 
   5:             address="soap.udp://239.255.255.19:5000/RemoteEventService" 
   6:             binding="customBinding"
   7:             contract="EPiServer.Events.ServiceModel.IEventReplication" />
   8:     </client>
   9:     <bindings>
  10:         <custombinding>
  11:             <binding name="RemoteEventsBinding">
  12:                 <binarymessageencoding />
  13:                 <udptransport multicast="true" />
  14:             </binding>
  15:         </custombinding>
  16:     </bindings>
  17:     <extensions>
  18:         <bindingelementextensions>
  19:             <add name="udpTransport" type="Microsoft.ServiceModel.Samples.UdpTransportElement, EPiServer.Events" />
  20:         </bindingelementextensions>
  21:     </extensions>
  22:     <services>
  23:         <service name="EPiServer.Events.Remote.EventReplication">
  24:             <endpoint bindingconfiguration="RemoteEventsBinding" name="RemoteEventServiceEndPoint" address="soap.udp://239.255.255.19:5000/RemoteEventService" binding="customBinding" contract="EPiServer.Events.ServiceModel.IEventReplication" />
  25:         </service>
  26:     </services>
  27: </system.servicemodel>
  28: <system.webserver>
  29:     <modules runallmanagedmodulesforallrequests="true">
  30:         <add name="EventSubscriberHostModule" type="EPiServer.EventSubscriberHostModule, EPiServer" />
  31:     </modules>
  32: </system.webserver>