11/29/09

PowerShell Load Assembly Function

LoadAssembly loads an assembly into the PowerShell session.

Note that unloading an assembly from PowerShell requires closing the PowerShell window, so close the window before trying to rebuild or delete a loaded assembly.
function loadAssembly($file)
{
  [system.reflection.assembly]::loadfile($file) | out-null
}

Example
loadAssembly c:\lib\file.dll

11/27/09

YUI Compressor for JavaScript and CSS

The YUI Compressor can be used to compress JavaScript and CSS files. It also offers a low-security JavaScript obfuscation option via local symbol renaming - it does not rename functions.

The tool requires the Java SDK 1.4 or later and can be run from the command line. The command line is useful because formatted, commented JavaScript can be used for development and compressed versions can be easily generated for test and prod.

To avoid compression build errors, verify your file text encoding. For Visual Studio UTF-8, make sure to select the "Unicode UTF-8 without signature" encoding from the File - Advanced Save Options menu. Then include the charset UTF-8 option in the command.

Example - run as one line
java -jar c:\lib\yui\yuicompressor-2.4.2.jar
c:\code\web\scripts\file.js
-o c:\code\web\scripts\file.min.js
--charset utf-8

11/22/09

PowerShell SharpZipLib Script

These PowerShell scripts can be used to zip and unzip files.

Zip operates on file lists such as output from the Get-ChildItem cmdlet. You can set the zip file root folder by specifying the leading folder path to remove. The Where-Object cmdlet can be used for advanced filtering. This function does not zip empty folders. See the SharpZipLib wiki for examples of zipping empty folders. Also, this function does not work with files that are locked, such as log files that are being written.

The free SharpZipLib .NET Zip assembly is used for zip functionality. You'll need to download the assembly and load it into PowerShell to run the scripts. Note that after you download or copy the assembly locally, you may have to trust the assembly. To do this, right-click the assembly and trust (unblock) it. Other related info can be found the SharpZipLib wiki.

These PowerShell scripts were tested using SharpZipLib version 0.85.5.
Strong name: ICSharpCode.SharpZipLib, Version=0.85.5.452, Culture=neutral, PublicKeyToken=1b03e6acf1164f73
function zip($zipFile, $leadingFolderPathToRemove)
{
  begin
  {
    $zip = [icSharpCode.sharpZipLib.zip.zipFile]::create($zipFile)
    $zip.beginUpdate()
  
    #add trailing backslash if necessary
    $leadingFolderPathToRemove = (join-path $leadingFolderPathToRemove '\')
  }
  process
  {
    #remove leading folder path from file name
    $file = $_.fullName.remove(0, $leadingFolderPathToRemove.length)
    $zip.add($_.fullName, $file)
  }
  end
  {
    $zip.commitUpdate()
    '{0} files zipped' -f $zip.count
    $zip.close()
  }
}

function unzip($zipFile, $unzipToFolder)
{
  $zip = new-object icSharpCode.sharpZipLib.zip.fastZip
  $zip.extractZip($zipFile, $unzipToFolder, $null)
}

Examples
loadAssembly c:\lib\sharpZipLib\ICSharpCode.SharpZipLib.dll

#zip all files from folder c:\code\web\ into c:\temp\web.zip
gci c:\code\web\* -include *.* -recurse -force | zip c:\temp\web.zip c:\code\web\

#only files modified 11-22-2009 or later
gci c:\code\web\* -include *.* -recurse -force |
where {$_.lastWriteTime -ge [dateTime]"11-22-2009 00:00"} |
zip c:\temp\web.zip c:\code\web\

#exclude files: *.csproj*, *.pdb, *.refresh, *.sln, *.suo
#exclude folders: debug, obj, release, properties
$excludeRegex = '(\.(csproj(.*)|pdb|refresh|sln|suo)$)|(\\(debug|obj|release|properties)(\\|$))'
gci c:\code\web\* -include *.* -recurse -force |
where {$_.fullName -notMatch $excludeRegex} |
zip c:\temp\web.zip c:\code\web\

#unzip c:\temp\web.zip into folder c:\temp\unzip\web\
unzip c:\temp\web.zip c:\temp\unzip\web

11/15/09

PowerShell Find Files Script

FindFiles returns a list of files that contain the search text. The search can be plain text or a regular expression.

This function is similar to using the Select-String cmdlet with the -list switch parameter. The difference is that FindFiles supports searching across line breaks. See the examples that use the "dot matches line breaks" regex pattern (?s).
function findFiles($text)
{
begin
{
$count = 0
}
process
{
$data = [system.io.file]::readAllText($_.fullname)
if ($data -match $text) #if matches at least once...
{
$_.fullname
$count += 1
}
}
end
{
"$count files found"
}
}

Examples
#find files containing "abc"
gci c:\* -include *.txt | findFiles 'abc'

#find files containing "abc" or "xyz"
gci c:\* -include *.txt | findFiles 'abc|xyz'

#find files containing "abc", including across line breaks
gci c:\* -include *.txt | findFiles '(?s)a.*bc|ab.*c'

#find files containing "<abc>" tags, including across line breaks, and empty tags
gci c:\* -include *.txt | findfiles '(?s)<abc>.*</abc>|<abc/>'