Public/xcrypt/Expand-String.ps1
function Expand-String { <# .SYNOPSIS Expanding a string expression. Can handle Powershell string expressions or Environment variable expansion. .DESCRIPTION Expanding a string expression. Can handle Powershell string expressions or Environment variable expansion. .PARAMETER String The string that you want expanded. .PARAMETER EnvironmentVariable A switch to expand the string expression as an environment variable. .PARAMETER PowershellString A switch to expand the string expression as a Powershell string .PARAMETER StringResource A switch to expand the string expression as a StringResource which can be found in desktop.ini and registry entries. An example is '@%SystemRoot%\system32\shell32.dll,-21770' .PARAMETER IncludeInput A switch to determine if you want the original string expression to appear in the output. Aliased to 'IncludeOriginal' .EXAMPLE # Expanding Powershell string Expand-String '$psculture' Assuming you have English US as the local installed culture this would return: en-US .EXAMPLE # Expanding Powershell string including original string in the output Expand-String '$psculture' -PsString -IncludeInput #Assuming you have English US as the local installed culture this would return: String Conversion Expanded ------ ---------- -------- $psculture PsString en-US .EXAMPLE # Expanding environment variable Expand-String -String '%PROCESSOR_ARCHITECTURE%' -EnvironmentVariable #Assuming you are a 64 bit machine, the function would return: AMD64 .EXAMPLE # Expanding environment variable including orginal string Expand-String -String '%PROCESSOR_ARCHITECTURE%' -EnvironmentVariable -IncludeInput #Assuming you are a 64 bit machine, the function would return: String Conversion Expanded ------ ---------- -------- %PROCESSOR_ARCHITECTURE% EnvVar AMD64 .EXAMPLE # Resource strings are stored within DLL's and are referenced by an ID number. An example would be # @%SystemRoot%\system32\shell32.dll,-21770 # and they are found in Desktop.ini files and also the registry. $ResourceString = (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\LanmanWorkstation').DisplayName Expand-String -String $ResourceString -StringResource -IncludeInput # Would return the following if your Windows install culture was en-US String Conversion Expanded ------ ---------- -------- @%systemroot%\system32\wkssvc.dll,-100 StrResource Workstation .NOTES The c# source code was found by me on the Internet, but I can't determine where I originally found it. The ability to expand a StrResource is thanks to that code. #> #region parameter [CmdletBinding(DefaultParameterSetName = 'PsString', ConfirmImpact = 'None')] [OutputType('string')] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '')] param( [Parameter(Mandatory, HelpMessage = 'Enter a string to expand', Position = 0, ValueFromPipeline, ParameterSetName = 'PsString')] [Parameter(Mandatory, HelpMessage = 'Enter a string to expand', Position = 0, ValueFromPipeline, ParameterSetName = 'EnvVar')] [Parameter(Mandatory, HelpMessage = 'Enter a string to expand', Position = 0, ValueFromPipeline, ParameterSetName = 'StrResource')] [string[]] $String, [Parameter(ParameterSetName = 'PsString')] [Alias('PsString')] [switch] $PowershellString, [Parameter(ParameterSetName = 'EnvVar')] [Alias('EnvVar')] [switch] $EnvironmentVariable, [Parameter(ParameterSetName = 'StrResource')] [Alias('StrResource')] [switch] $StringResource, [Parameter(ParameterSetName = 'PsString')] [Parameter(ParameterSetName = 'EnvVar')] [Parameter(ParameterSetName = 'StrResource')] [Alias('IncludeOriginal')] [switch] $IncludeInput ) #endregion parameter begin { Write-Invocation $MyInvocation Out-Verbose "ParameterSetName [$($PsCmdlet.ParameterSetName)]" $source = @' using System; using System.Runtime.InteropServices; using System.Text; public class PFExtractData { [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi)] private static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)]string lpFileName); [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern int LoadString(IntPtr hInstance, int ID, StringBuilder lpBuffer, int nBufferMax); [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool FreeLibrary(IntPtr hModule); public string ExtractStringFromDLL(string file, int number) { IntPtr lib = LoadLibrary(file); StringBuilder result = new StringBuilder(2048); LoadString(lib, number, result, result.Capacity); FreeLibrary(lib); return result.ToString(); } } '@ Add-Type -TypeDefinition $source $ExtractData = New-Object -TypeName PFExtractData } process { foreach ($currentString in $String) { Out-Verbose "Current string is [$currentString]" $prop = ([ordered] @{ String = $currentString }) switch ($PsCmdlet.ParameterSetName) { 'PsString' { $prop.Conversion = 'PsString' $ReturnVal = $ExecutionContext.InvokeCommand.ExpandString($currentString) } 'EnvVar' { $prop.Conversion = 'EnvVar' $ReturnVal = [System.Environment]::ExpandEnvironmentVariables($currentString) } 'StrResource' { $prop.Conversion = 'StrResource' $Resource = $currentString -split ',' $ReturnVal = $ExtractData.ExtractStringFromDLL([Environment]::ExpandEnvironmentVariables($Resource[0]).substring(1), $Resource[1].substring(1)) # $ReturnVal = 'Placeholder' } } Out-Verbose "ReturnVal is [$ReturnVal]" $prop.Expanded = $ReturnVal if ($IncludeInput) { New-Object -TypeName psobject -Property $prop } else { Write-Output -InputObject $ReturnVal } } } end { Out-Verbose $fxn "Complete." } } |