Skip to content

Instantly share code, notes, and snippets.

@josheinstein
Created April 30, 2012 16:10
Show Gist options
  • Save josheinstein/2559629 to your computer and use it in GitHub Desktop.
Save josheinstein/2559629 to your computer and use it in GitHub Desktop.
Test-Requirement - Would love to see something like this in PowerShell.
##############################################################################
#.SYNOPSIS
# Ensures that certain dependencies are available in the current environment.
#
#.DESCRIPTION
# Test-Requirement will throw an exception if the requirement is not met, or
# it will write a verbose message if the requirement succeeds. It is not
# intended to be used in a conditional statement, rather it is intended to be
# used at the top of your function as a declarative statement in a scope that
# will be aborted if an exception is thrown.
#
# Test-Requirement promotes clean, self-documenting scripts that can bail out
# early if certain requirements are not met and can greatly reduces the amount
# of clutter in scripts in testing for certain commands, aliases, assemblies,
# COM objects, etc.
#
#.PARAMETER ErrorMessage
# Overrides the exception message thrown when the requirement is not met.
#.PARAMETER Version
# Requires a minimum PowerShell runtime version.
#.PARAMETER Administrator
# The current script must be running as a user with admin rights.
#.PARAMETER Assembly
# The full or partial name of a .NET assembly that must be loaded.
#.PARAMETER ProgID
# The specified COM ProgID must be registered in HKLM or HKCU.
#.PARAMETER Command
# The specified name must exist as a Cmdlet, Function, or Alias.
#.PARAMETER Variable
# The specified name must exist as a variable
#.PARAMETER Module
# A module or PSSnapin with the specified name must be loaded
#.PARAMETER Script
# The specified script file must exist (equivalent to -File)
#.PARAMETER Directory
# The specified path must exist as a directory
#.PARAMETER File
# The specified path must exist as a file
#.PARAMETER PSDrive
# The specified PSDrive must be attached
#
#.EXAMPLE
# Test-Requirement -Administrator
#.EXAMPLE
# Test-Requirement -Version 2.0 -ErrorMessage 'Upgrade your PowerShell!'
#.EXAMPLE
# Test-Requirement -Module Pscx
##############################################################################
function Test-Requirement {
[CmdletBinding(DefaultParameterSetName='Module')]
param (
[Parameter()]
[String] $ErrorMessage,
[Alias('PSSnapIn')]
[Parameter(Mandatory=$true, ParameterSetName='Module', Position=1)]
[String] $Module,
[Parameter(Mandatory=$true, ParameterSetName='Administrator')]
[Switch] $Administrator,
[Parameter(Mandatory=$true, ParameterSetName='Version')]
[String] $Version,
[Parameter(Mandatory=$true, ParameterSetName='Assembly')]
[String] $Assembly,
[Parameter(Mandatory=$true, ParameterSetName='ProgID')]
[String] $ProgID,
[Parameter(Mandatory=$true, ParameterSetName='Command')]
[String] $Command,
[Parameter(Mandatory=$true, ParameterSetName='Variable')]
[String] $Variable,
[Parameter(Mandatory=$true, ParameterSetName='Script')]
[String] $Script,
[Parameter(Mandatory=$true, ParameterSetName='Directory')]
[String] $Directory,
[Parameter(Mandatory=$true, ParameterSetName='File')]
[String] $File,
[Parameter(Mandatory=$true, ParameterSetName='PSDrive')]
[String] $PSDrive
)
if ( $Administrator ) {
try {
$Identity = [Security.Principal.WindowsIdentity]::GetCurrent()
$Principal = New-Object Security.Principal.WindowsPrincipal $Identity
if ( -not $ErrorMessage ) { $ErrorMessage = "ADMIN CHECK:`n$($Identity.Name) is not an administrator." }
if ( $Principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) ) {
Write-Verbose "ADMIN CHECK:`n$($Identity.Name) is an administrator."
}
else {
throw $ErrorMessage
}
}
finally {
if ($Identity) { $Identity.Dispose() }
}
}
if ( $Version ) {
$V = New-Object System.Version $Version
$CV = $PSVersionTable.PSVersion
if ( -not $ErrorMessage ) { $ErrorMessage = "VERSION CHECK: $V`nCurrent version is $CV is lower than required version $V." }
if ( $CV -ge $V ) { Write-Verbose "VERSION CHECK: $V`nCurrent PowerShell version is $CV" }
else { throw $ErrorMessage }
}
if ( $Assembly ) {
if ( -not $ErrorMessage ) { $ErrorMessage = "ASSEMBLY CHECK: $Assembly`nThis script requires assembly $Assembly to be loaded first." }
$Found = $false
foreach ( $Asm in [AppDomain]::CurrentDomain.GetAssemblies() ) {
$AsmName = $Asm.GetName()
if ( $AsmName.Name -like $Assembly -or $AsmName.FullName -like $Assembly ) {
$Found = $true
break;
}
}
if ( $Found ) { Write-Verbose "ASSEMBLY CHECK: $Assembly`n$AsmName is loaded." }
else { throw $ErrorMessage }
}
if ( $ProgID ) {
if ( -not $ErrorMessage ) { $ErrorMessage = "PROGID CHECK: $ProgID`nThis script requires COM object $ProgID which is not registered." }
if ( Test-Path "HKLM:\Software\Classes\$ProgID" ) {
Write-Verbose "PROGID CHECK: $ProgID`n$ProgID was registered in HKLM."
}
elseif ( Test-Path "HKCU:\Software\Classes\$ProgID" ) {
Write-Verbose "PROGID CHECK: $ProgID`n$ProgID was registered in HKCU."
}
else {
throw $ErrorMessage
}
}
if ( $Command ) {
if ( -not $ErrorMessage ) { $ErrorMessage = "COMMAND CHECK: $Command`nThis script requires a command named $Command which was not found." }
if ( Get-Command $Command -ErrorAction SilentlyContinue ) {
Write-Verbose "COMMAND CHECK: $Command`n$Command is available."
}
else {
throw $ErrorMessage
}
}
if ( $Variable ) {
if ( -not $ErrorMessage ) { $ErrorMessage = "VARIABLE CHECK: $Variable`nThis script requires a variable named $Variable which was not found." }
if ( Get-Variable $Variable -ErrorAction SilentlyContinue ) {
Write-Verbose "VARIABLE CHECK: $Variable`n$Variable (Found)"
}
else {
throw $ErrorMessage
}
}
if ( $Module ) {
if ( -not $ErrorMessage ) { $ErrorMessage = "MODULE CHECK: $Module`nThis script requires module $Module to be loaded first." }
if ( Get-PSSnapin $Module -ErrorAction SilentlyContinue ) {
Write-Verbose "MODULE CHECK: $Module`nPSSnapIn Found"
}
elseif ( Get-Module $Module -ErrorAction SilentlyContinue ) {
Write-Verbose "MODULE CHECK: $Module`nModule Found"
}
else {
throw $ErrorMessage
}
}
if ( $Script ) {
if ( -not $ErrorMessage ) { $ErrorMessage = "SCRIPT CHECK: $Script`nThis script requires the script file $Script which was not found." }
if ( Test-Path $Script -PathType Leaf ) {
Write-Verbose "SCRIPT CHECK: $Script`nScript found."
}
else {
throw $ErrorMessage
}
}
if ( $Directory ) {
if ( -not $ErrorMessage ) { $ErrorMessage = "DIRECTORY CHECK: $Directory`nThis script requires a directory $Directory which was not found." }
if ( Test-Path $Directory -PathType Container ) {
Write-Verbose "DIRECTORY CHECK: $Directory`nDirectory found."
}
else {
throw $ErrorMessage
}
}
if ( $File ) {
if ( -not $ErrorMessage ) { $ErrorMessage = "FILE CHECK: $File`nThis script requires a file $File which was not found." }
if ( Test-Path $File -PathType Leaf ) {
Write-Verbose "FILE CHECK: $File`nFile found."
}
else {
throw $ErrorMessage
}
}
if ( $PSDrive ) {
if ( -not $ErrorMessage ) { $ErrorMessage = "PSDRIVE CHECK: $($PSDrive):\`nThis script requires a PSDrive named $PSDrive but it does not exist." }
if ( Get-PSDrive -Name $PSDrive -ErrorAction SilentlyContinue ) {
Write-Verbose "PSDRIVE CHECK: $($PSDrive):\`nPSDrive found."
}
else {
throw $ErrorMessage
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment