Skip to content

Instantly share code, notes, and snippets.

@cdhunt
Created January 3, 2017 18:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cdhunt/8da4cc7ace33cdc12dcaaae1eed91fda to your computer and use it in GitHub Desktop.
Save cdhunt/8da4cc7ace33cdc12dcaaae1eed91fda to your computer and use it in GitHub Desktop.
Example usage of Custom Attributes
. "$PSScriptRoot\attr_common.ps1"
class PowerShellExecutable : Executable
{
[ExecutableArgument('File')]
[string]$File
[ExecutableArgument('Password', $true)]
[string]$Password
PowerShellExecutable([Hashtable]$parameters)
{
$type = $this.GetType()
$properties = $type.GetProperties()
foreach($property in $properties)
{
if($parameters.ContainsKey($property.Name) -and $parameters[$property.Name] -ne $null)
{
$property.SetValue($this, $parameters[$property.Name])
}
}
}
}
function TestFunc
{
[CmdletBinding()]
param
(
[string]$Path,
[string]$File,
[string]$Password,
[string]$Junk
)
[PowerShellExecutable]::new($PSBoundParameters)
}
TestFunc -Path "C:\windows\system32\WindowsPowerShell\v1.0\powershell.exe" -File "C:\Path\To\script.ps1" -Password "TestPass" -Junk "junk"
class ExecutableArgument : System.Attribute
{
[string]$Name
[bool]$Sensitive
[bool]$EncloseValueIfSpacesPresent = $true
[ParameterStyle]$ParameterStyle
[ParameterValueSeparator]$Separator
[object]$Value
ExecutableArgument([string]$name)
{
$this.Name = $name
$this.Sensitive = $false
}
ExecutableArgument([string]$name, [bool]$sensitive)
{
$this.Name = $name
$this.Sensitive = $sensitive
}
ExecutableArgument([string]$name, [bool]$sensitive, [bool]$encloseValue, [ParameterStyle]$style, [ParameterValueSeparator]$separator)
{
$this.Name = $name
$this.Sensitive = $sensitive
$this.EncloseValueIfSpacesPresent = $true
$this.ParameterStyle = $style
$this.Separator = $separator
}
}
enum ParameterStyle
{
Slash
Backslash
Dash
DoubleDash
}
enum ParameterValueSeparator
{
Space
Colon
}
class Executable
{
[string]$Path
[void] Invoke()
{
Invoke-Expression -Command $this.GetInvokeString()
}
[string] GetInvokeString()
{
$cmd = "& $($this.Path) "
$params = @()
foreach($param in $this.GetArguments())
{
$cmdParam = switch($param.ParameterStyle)
{
Slash { '/' }
Backslack { '\' }
Dash { '-' }
DoubleDash { '--' }
}
$cmdParam += $param.Name
$cmdParam += switch($param.Separator)
{
Space { ' ' }
Colon { ':' }
}
if($param.EncloseValueIfSpacesPresent -eq $true -and $param.Value -match '\s')
{
$cmdParam += '"'
$cmdParam += $param.Value
$cmdParam += '"'
}
else
{
$cmdParam += $param.Value
}
$params += $cmdParam
}
$cmd += $params -join ' '
return $cmd
}
[ExecutableArgument[]] GetArguments()
{
$type = $this.GetType()
$properties = $type.GetProperties()
$result = @()
foreach($property in $properties)
{
$attr = [System.Attribute]::GetCustomAttribute($property, [ExecutableArgument])
if($attr -ne $null)
{
$attr.Value = $property.GetValue($this)
$result += $attr
}
}
return $result
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment