Allow passing $true/$false as parameter to script using -File (#4178)

Using powershell.exe to execute a PowerShell script using -File currently provides no way to pass $true/$false as parameter values. Current behavior is that -File accumulates passed parameters as strings only.

Fix is to special case this based on discussion with PS-Committee to support $true/$false as parsed values to parameters. Switch values is also supported as currently documented syntax doesn't work.
This commit is contained in:
Steve Lee
2017-08-01 14:41:31 -07:00
committed by Dongbo Wang
parent e829053e9e
commit e64e68bcdc
2 changed files with 67 additions and 6 deletions
@@ -858,6 +858,22 @@ namespace Microsoft.PowerShell
// of the script to evaluate. If -file comes before -command, it will
// treat -command as an argument to the script...
bool TryGetBoolValue(string arg, out bool boolValue)
{
if (arg.Equals("$true", StringComparison.OrdinalIgnoreCase) || arg.Equals("true", StringComparison.OrdinalIgnoreCase))
{
boolValue = true;
return true;
}
else if (arg.Equals("$false", StringComparison.OrdinalIgnoreCase) || arg.Equals("false", StringComparison.OrdinalIgnoreCase))
{
boolValue = false;
return true;
}
boolValue = false;
return false;
}
++i;
if (i >= args.Length)
{
@@ -922,7 +938,6 @@ namespace Microsoft.PowerShell
i++;
Regex argPattern = new Regex(@"^.\w+\:", RegexOptions.CultureInvariant);
string pendingParameter = null;
// Accumulate the arguments to this script...
@@ -939,17 +954,25 @@ namespace Microsoft.PowerShell
}
else if (!string.IsNullOrEmpty(arg) && SpecialCharacters.IsDash(arg[0]))
{
Match m = argPattern.Match(arg);
if (m.Success)
int offset = arg.IndexOf(':');
if (offset >= 0)
{
int offset = arg.IndexOf(':');
if (offset == arg.Length - 1)
{
pendingParameter = arg.TrimEnd(':');
}
else
{
_collectedArgs.Add(new CommandParameter(arg.Substring(0, offset), arg.Substring(offset + 1)));
string argValue = arg.Substring(offset + 1);
string argName = arg.Substring(0, offset);
if (TryGetBoolValue(argValue, out bool boolValue))
{
_collectedArgs.Add(new CommandParameter(argName, boolValue));
}
else
{
_collectedArgs.Add(new CommandParameter(argName, argValue));
}
}
}
else
+39 -1
View File
@@ -201,7 +201,45 @@ Describe "ConsoleHost unit tests" -tags "Feature" {
$observed[1] | Should Be "bar"
}
It "-File should return exit code from script: <Filename>" -TestCases @(
It "-File should be able to pass bool string values as string to parameters: <BoolString>" -TestCases @(
# validates case is preserved
@{BoolString = '$truE'},
@{BoolString = '$falSe'},
@{BoolString = 'trUe'},
@{BoolString = 'faLse'}
) {
param([string]$BoolString)
Set-Content -Path $testdrive/test.ps1 -Value 'param([string]$bool) $bool'
$observed = & $powershell -NoProfile -Nologo -File $testdrive/test.ps1 -Bool $BoolString
$observed | Should Be $BoolString
}
It "-File should be able to pass bool string values as string to positional parameters: <BoolString>" -TestCases @(
# validates case is preserved
@{BoolString = '$tRue'},
@{BoolString = '$falSe'},
@{BoolString = 'tRUe'},
@{BoolString = 'fALse'}
) {
param([string]$BoolString)
Set-Content -Path $testdrive/test.ps1 -Value 'param([string]$bool) $bool'
$observed = & $powershell -NoProfile -Nologo -File $testdrive/test.ps1 $BoolString
$observed | Should BeExactly $BoolString
}
It "-File should be able to pass bool string values as bool to switches: <BoolString>" -TestCases @(
@{BoolString = '$tRue'; BoolValue = 'True'},
@{BoolString = '$faLse'; BoolValue = 'False'},
@{BoolString = 'tRue'; BoolValue = 'True'},
@{BoolString = 'fAlse'; BoolValue = 'False'}
) {
param([string]$BoolString, [string]$BoolValue)
Set-Content -Path $testdrive/test.ps1 -Value 'param([switch]$switch) $switch.IsPresent'
$observed = & $powershell -NoProfile -Nologo -File $testdrive/test.ps1 -switch:$BoolString
$observed | Should Be $BoolValue
}
It "-File should return exit code from script" -TestCases @(
@{Filename = "test.ps1"},
@{Filename = "test"}
) {