Writing Cmdlets with PowerShell Script

One of the really cool features of MSH is that you can write functions that behave like cmdlets.  This is nice since you don’t have to immediately drop down to C# and write a PS Snapin just to get "cmdlet like" functionality.  Here’s a "cmdlet" function, modified from the PowerShell Getting Started Guide, to provide "touch" functionality:
 
function touch-file([string[]]$paths) {
  begin {
    function updateFileSystemInfo([System.IO.FileSystemInfo]$fsInfo) {
      $datetime = get-date
      $fsInfo.CreationTime = $datetime
      $fsInfo.LastWriteTime = $datetime
      $fsInfo.LastAccessTime = $datetime
    }
   
    function touchExistingFile($arg) {
      if ($arg -is [System.IO.FileSystemInfo]) {
        updateFileSystemInfo($arg)
      }
      else {
        $resolvedPaths = resolve-path $arg
        foreach ($rpath in $resolvedPaths) {
          if (test-path -type Container $rpath) {
            $fsInfo = new-object System.IO.DirectoryInfo($rpath)
          }
          else {
            $fsInfo = new-object System.IO.FileInfo($rpath)
          }
          updateFileSystemInfo($fsInfo)
        }
      }
    }
   
    function touchNewFile([string]$path) {
      $null > $path
    }
  }
 
  process {
    if ($_) {
      if (test-path $_) {
        touchExistingFile($_)
      }
      else {
        touchNewFile($_)
      }
    }
  }
 
  end {
    if ($paths) {
      foreach ($path in $paths) {
        if (test-path $path) {
          touchExistingFile($path)
        }
        else {
          touchNewFile($path)
        }
      }
    }
  }
}
 
This approach allows you to use touch-file in several different ways.  The primary mechanism for doing is is to handle piped data via the "process" block and then to handle function arguments via the "end" block.  Note that when dealing with paths you want to use the Resolve-Path cmdlet to expand wild cards.  With these tweaks, you can use this function in several different ways including within the pipe e.g.:
 
PS> touch-file foo.txt
PS> touch-file *.bak
PS> gci . -rec -fil "*.cs" | touch-file
 
This entry was posted in PowerShell. Bookmark the permalink.

Leave a comment