Tag Archives: powershell

Beta testing and error handling

Here is a simple snippet that you can run to output all exceptions in a script.

$ErrorActionPreference = "SilentlyContinue"


# Debug function, dumps all errors in $Error variable to file

Function Dump-Errors(){
        [Parameter(Position=0, Mandatory = $True)]
    $Error | Add-Content $Logfile

Dump-Errors -logfile "c:\temp\script.log"

If you look at the code, the cmdlet “IWillProduceAnError” is most likely not recognized and will produce an exception.
However, you have the $ErrorActionPreference set to SilentlyContinue so nothing will show for the user.

This is where the dump-errors function will help you catch errors you would otherwise never see.

Place the function in your code and make sure the last line to run is the function.
It will output all exceptions in the $Error variable to a file. You can then later collect the file from the users you know are beta testing and use the Try/Catch statements to correct your code. Combine this with the Powershell auto updater in silent mode and the user will never know you updated the code.

wget for windows

ever wanted to use wget in Powershell? This short function allows you to wget to local directory.

function wget($urlpath){
  $directory = (get-location).path

  $filename = $urlpath.Split("/")[-1]
  $file = $directory+"\"+$filename

  $webclient = New-Object System.Net.WebClient

Simply enter the function into your current powershell session and try it out.
wget http://upload.wikimedia.org/wikipedia/en/f/f4/The_Scream.jpg

If you want to permanently have access to this command add the function to the following file: “%windir%\system32\WindowsPowerShell\v1.0\profile.ps1

For more information on Powershell profiles, read this article:

Powershell auto updater

I wrote this short script to keep local scripts up to date with server versions.

Makes it easier to handle scripts that are added with initial version through task sequence or other onetime distributions. The requirement is for the scripts to have the variable $CurrentVersion = <int/double>

Example script, located on the central/repository:

$CurrentVersion = 1.1
$form = New-Object 'System.Windows.Forms.Form'

If the local/current script contains $CurrentVersion = 1.0 or less it will get updated once the launcher has been run.
Launcher code below:

# Following variables control the paths used in script

# Retrieve the directory of script.
$Script:G_runDir = Split-Path -Parent $MyInvocation.MyCommand.Path

# Name of the script to update.
$Script:G_Script  = "ScriptPath.ps1"

# Where repository version is located.
$Script:G_RepositoryPath = "\\$env:userdnsdomain\Path\To\Script"

# Build paths for scripts. Do not change!
$Script:G_LocalScript = "$G_runDir\$G_Script"
$Script:G_CentralScript = "$G_RepositoryPath\$G_Script"

Function MainFunction(){

    if(Test-Path $G_CentralScript){

        $LocalInfo = Get-Info -ScriptPath $G_LocalScript
        $CentralInfo = Get-Info -ScriptPath $G_CentralScript
        $LocalVersion = $LocalInfo.Version
        $LocalChecksum = $LocalInfo.Checksum

        $CentralVersion = $CentralInfo.Version
        $CentralChecksum = $CentralInfo.Checksum

        Write-Host "Local Version: $LocalVersion. Central Version: $CentralVersion"
        If($LocalChecksum -ne $CentralChecksum){
            If($LocalVersion -ge $CentralVersion){
                Write-Host "Local script corrupt"
                Write-Host "Updating script"
                Copy-Item "$G_CentralScript" -Destination "$G_runDir" -Force
                Write-host "Script pdated"
                Write-Error $_
        }Elseif($LocalChecksum -eq $CentralChecksum){
            Write-Host "Script up to date"
        Write-host "Local Version: $LocalVersion. Could not find $G_CentralScript."
} # End Function

# Gets version of scripts.
Function Get-Info{
    $Return = @{"Checksum" = "Null";"Version" = 0}
    $MD5 = New-Object 'System.Security.Cryptography.MD5CryptoServiceProvider'
    If(Test-Path $ScriptPath){

            $Checksum = [System.BitConverter]::ToString($MD5.ComputeHash([System.IO.File]::ReadAllBytes($ScriptPath)))
            $Return.Checksum = $Checksum
            Write-Error $_

        $Script = (get-content $ScriptPath) | Where-Object{$_ -like "*APP_VER*"}
            Return Write-Host "$ScriptPath does not contain any valid version information!"
                # Uses invoke-expression to set version variable.
                $ScriptBlock = $Script | Where-Object{$_.StartsWith("Set-Variable")}
                If($ScriptBlock.GetType().Name -eq "String"){
                    Invoke-Expression $ScriptBlock
                    If(($APP_VER.GetType() -eq [Double]) -or ($APP_VER.GetType() -eq [Int])){
                        $Return.Version = $APP_VER
                Write-Error $_
    Return $Return

# Prompts for input and launches script.

Function Launch-Application{
        .{Powershell.exe -File "$Script:G_LocalScript"}
        Write-Error $_
} # End function

#=== Call Main function =========================================================


Just copy-paste this and change the paths and you should be good. If you’re running a console application you might want to change the “-Windowstyle” in Start-Script function to “normal”
Currently it waits until any key has been pressed but if you want it to launch instantly just comment out the line