Friday, March 20, 2015

PowerShell: Identifying Strongly or Weakly Typed Variables

PowerShell is a loosely typed language, which means we can run something like this and PowerShell will automatically select the data type for us.

$var = 123;
$var.GetType();

Results in: System.Int32

And if we go and change the value to a string, PowerShell just naturally changes the datatype as required for us.

$var = "string";
$var.GetType();

Results in: System.String 

Now if you are like me and grew up in a strict language, then you may prefer to Strongly Type your variables. There are actually very good reasons for doing this as it guarantees the data type you will be working with, particularly from user input (although there are input validation methods you can use in addition to this too).

To strongly type a variable we prefix the variable name (at creation) with the desired type.
[string]$var = "string";

Now this what I would consider good coding practice. So how do we determine if variables have been strongly typed. The following script will create an array to hold all known system variables, because we don't want to mess around with them. Then it will use Get-Variable and look at the Attributes property of a variable to determine if the type conversion was set. Now this method could also be used for some of the other attribute options (e.g. range validation, etc)


<#
This script can be used to check for Strongly and Weakly typed variables defined within the session
Things to note:
- Variables created in child scopes which have ended will not be visible
- Some System Variables may appear in the list
#>

#create an array to hold all the known system variables (variables from other modules are not included here)
$SystemVars = @('$'
    , '?'
    ,'^'
    ,'true'
    ,'false'
    ,'args'
    ,'Error'
    ,'ErrorView'
    ,'ExecutionContext'
    ,'FormatEnumerationLimit'
    ,'HOME'
    ,'Host'
    ,'input'
    ,'ConfirmPreference'
    ,'ConsoleFileName'
    ,'DebugPreference'
    ,'ErrorActionPreference'
    ,'MaximumAliasCount'
    ,'MaximumDriveCount'
    ,'MaximumErrorCount'
    ,'MaximumFunctionCount'
    ,'MaximumHistoryCount'
    ,'MaximumVariableCount'
    ,'MyInvocation'
    ,'NestedPromptLevel'
    ,'null'
    ,'OutputEncoding'
    ,'PID'
    ,'profile'
    ,'ProgressPreference'
    ,'PSBoundParameters'
    ,'PSCommandPath'
    ,'PSCulture'
    ,'PSDefaultParameterValues'
    ,'PSEmailServer'
    ,'PSHOME'
    ,'psISE'
    ,'PSScriptRoot'
    ,'PSSessionApplicationName'
    ,'PSSessionConfigurationName'
    ,'PSSessionOption'
    ,'PSUICulture'
    ,'psUnsupportedConsoleApplications'
    ,'PSVersionTable'
    ,'PWD'
    ,'ShellId'
    ,'StackTrace'
    ,'SystemVars'
    ,'VerbosePreference'
    ,'WarningPreference'
    ,'WhatIfPreference'
)

#view all variables and report if Weakly or Strongly typed
Get-Variable -Exclude $SystemVars | Select Name, @{Name='TypedState';Expression={
    If ($_.Attributes -match 'System.Management.Automation.ArgumentTypeConverterAttribute') {'Strong'} else {'Weak'}
}};


Legal Stuff: As always the contents of this blog is provided “as-is”. The information, opinions and views expressed are those of the author and do not necessarily state or reflect those of any other company with affiliation to the products discussed. This includes any URLs or Tools. The author does not accept any responsibility from the use of the information or tools mentioned within this blog, and recommends adequate evaluation against your own requirements to measure suitability.

No comments:

Post a Comment