I've got a release definition in vsts that needs access to a password I've defined as a secret variable in a variable group. I've linked that group to this release definition but when I run the task the parameter ends up blank. Is there anything special I need to do to get the value of a secret variable?
Definition of the powershell task that uses the password
Linked variable group
Error output:
2017-08-09T14:01:17.9262375Z ##[command]. 'C:\agent_work\r1\a\$(AGENT.BUILDDIRECTORY)\RCV\deploys\common\Get-FromArtifactory.ps1' -repoUsername developer -repoPassword -repoPath libs-snapshot-local
2017-08-09T14:01:18.8168538Z ##[error]C:\agent_work\r1\a\$(AGENT.BUILDDIRECTORY)\RCV\deploys\common\Get-FromArtifactory.ps1 : Missing an argument for parameter 'repoPassword'. Specify a parameter of type 'System.String' and try again.
Edited to add more info as requested.
This is the start of my Get-FromArtifactory.ps1
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[String]
$repoUsername,
[Parameter()]
[String]
$repoPassword,
# Other params
)
#setup credentials object for arty access
$secPassword = $repoPassword | ConvertTo-SecureString -asPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($repoUsername, $secPassword)
Edit 15/08/2017 - I've updated it to use quotes as suggested by #Marina-MSFT but it's still just passing in blank.
Amended script to print out part of password:
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[String]
$repoUsername,
[Parameter()]
[String]
$repoPassword,
#other params
)
write-host "pword $repoPassword"
write-host "1st char: $($repoPassword[0])"
2017-08-15T09:23:00.8606081Z ##[command]. 'C:\agent_work\r1\a\RCV\deploys\common\Get-FromArtifactory.ps1' -repoUsername developer -repoPassword "" -repoPath libs-snapshot-local -artifactName ipo-deposit-accounts_2.11 -artifactPath uk/gov/ipo -artifactVersion 0.1-SNAPSHOT -downloadDir C:\agent_work\r1\a
2017-08-15T09:23:02.3606174Z pword
2017-08-15T09:23:02.3606174Z 1st char:
Same with single quotes
2017-08-15T09:22:10.6573655Z ##[command]. 'C:\agent_work\r1\a\RCV\deploys\common\Get-FromArtifactory.ps1' -repoUsername developer -repoPassword '' -repoPath libs-snapshot-local -artifactName ipo-deposit-accounts_2.11 -artifactPath uk/gov/ipo -artifactVersion 0.1-SNAPSHOT -downloadDir C:\agent_work\r1\a
2017-08-15T09:22:11.2198723Z pword
2017-08-15T09:22:11.3761178Z 1st char:
I've got it working now, there were 2 things going on.
Having . in the name of a secret variable in a variable group
doesn't work. I recreated this issue in a separate release
definition/variable group.
Even after I removed the . in my var
names I still had to recreate the variable group for it to work.
Bug for issue with . in variable name raised here: https://developercommunity.visualstudio.com/content/problem/94475/secret-variable-in-variable-not-group-not-availabl.html
Related
I know how to add switch parameters to PowerShell scripts, but the name of the switch is always a (valid) identifier like -Enable because the name is generated from the backing PowerShell variable.
[CmdletBinding()]
param(
[switch] $Enable = $false
)
Some tools have switches like -2008. Normally, one would name the switch $2008 but this is not a valid identifier.
How can I implement such a switch as a boolean value in PowerShell?
Or in other words: How to specify a different parameter name then the backing variable?
Edit 1
I wasn't aware of number only variables (which is very strange for a programming language...). Anyhow, I created that example:
function foo
{ [CmdletBinding()]
param(
[switch] $2008
)
Write-Host "2008=$2008"
}
For this code, which is accepted as valid PowerShell, I get a auto completion as wanted. But when providing that parameter, I get this error message:
foo : Es wurde kein Positionsparameter gefunden, der das Argument "-2008" akzeptiert.
In Zeile:1 Zeichen:1
+ foo -2008
+ ~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [foo], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,foo
Translation: No positional parameter was found, that accepts the argument "-2008".
The purpose of the script is to provide translations / wrappers for command line interfaces.
Here is a set of standardized executables with parameters:
vcom.exe -2008 design.vhdl
vsim.exe -2008 design
Translation:
ghdl.exe -a --std=2008 design.vhdl
ghdl.exe -e --std=2008 design
ghdl.exe -r --std=2008 design
I would like to keep the feature of auto completion for parameters, otherwise I could process all remaining parameters and translate them by hand.
PowerShell doesn't support numeric parameters (See this answer).
Could a validateset be an acceptable solution to your problem ?
Validate set does benefit from the autocompletion feature and this is the next best thing, in my opinion, of what you wanted.
Foo & Foos — both are the same, except Foos accept multiple parameters.
foo -std 2008
foos -std 2008,2009,2010
function foo
{ [CmdletBinding()]
param(
[ValidateSet("2008",
"2009",
"2010",
"2011","2012")][INT]$std
)
Write-Host "std:$std"
}
function foos
{ [CmdletBinding()]
param(
[ValidateSet("2008",
"2009",
"2010",
"2011","2012")][INT[]]$std
)
$std | foreach {Write-Host "std: $_"}
}
foo -std 2008
foos -std 2008,2009,2010
This question already has answers here:
Function return value in PowerShell
(10 answers)
Closed 5 years ago.
I've written a PowerShell script to perform some pre-installation setup for a series of patches I'm deploying to client computers across our estate and I'm hitting a bit of an odd issue that I can't wrap my head around.
The setup patch checks the 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe.config' file due to a "feature" of PowerShell 2.0 whereby the application uses .NET Framework 2.0.0 by default instead of 4.5.2, preventing certain functions from being executed. If the file doesn't exist or the evaluated values don't match a specification, I add the XML file and provide the necessary values.
The command I run is as follows:
$psConfigDir = "C:\Windows\System32\WindowsPowerShell\v1.0"
$psConfigFileName = "powershell.exe.config"
[boolean]$psExeXml = Set-PSRuntimeConfigs -FilePath ( [String]::Format("{0}\{1}", $psConfigDir, $psConfigFileName) ) -CLRVersions #("v4.0.30319", "v2.0.50727")
...and the Set-PSRuntimeConfigs method is found in a PowerShell Module I created with the code below:
Function Set-PSRuntimeConfigs {
[CmdletBinding()]
Param(
[String]$FilePath,
[System.Collections.ArrayList]$CLRVersions
)
Try {
$xmlWriter = New-Object System.Xml.XmlTextWriter($FilePath, $null)
$xmlWriter.Formatting = "Indented"
$xmlWriter.Indentation = 4
$xmlWriter.WriteStartDocument()
$xmlWriter.WriteStartElement("configuration")
$xmlWriter.WriteStartElement("startup")
$xmlWriter.WriteAttributeString("useLegacyV2RuntimeActivationPolicy", $true)
$CLRVersions | ForEach-Object {
$xmlWriter.WriteStartElement("supportedRuntime")
$xmlWriter.WriteAttributeString("version", $_)
$xmlWriter.WriteEndElement()
}
$xmlWriter.WriteEndElement()
$xmlWriter.WriteEndElement()
$xmlWriter.WriteEndDocument()
$xmlWriter.Close()
$xmlWriter.Dispose()
return $true
} Catch {
echo "ERROR: Exception occurred during XML write process!"
echo "ERROR: Exception message: $($_.Exception.Message)"
return $false
}
}
However, the function is returning an InvalidCastException when trying to assign the result of the function to the $psExeXml variable. Oddly, PowerShell returns with an error stating that [System.Object()] cannot be converted to type [Boolean] despite the fact that only $true or $false is returned from the function.
My first thought is that an exception was being thrown by the function due to a code issue but the function is written to report the error in the prompt and just return $false in that case... Regardless, I'm stuck and can't figure out where to proceed with this...
If the function produces any output then the result will be an array containing the strings that were output and then the final element will be your boolean.
So for this code:
echo "ERROR: Exception occurred during XML write process!"
echo "ERROR: Exception message: $($_.Exception.Message)"
return $false
the function returns an array of two strings and a boolean.
I am writing a PowerShell function which can take pipeline input. Specifically I am testing it with Import-CSV. Many of the params are not mandatory, which means sometimes the CSV will not have those columns. For boolean values this is working as expected, but with string values, a missing CSV field yields a copy of the row object in the string field.
Here is an example problem parameter:
[Parameter(Mandatory=$False,
ValueFromPipeline=$True,
ValueFromPipelinebyPropertyName=$True,
HelpMessage="TCP Port of the remote server")]
[Alias('Port', 'Remote Server Port')]
[string]$RemoteServerPort = "5500",
Now, if the field is missing, I would expect the value to be "5500" as specified, but instead I get:
$RemoteServerPort = #{Name=KG; IP=10.1.1.1; Username=Admin; Password=}
I've done some looking around, but frankly I'm not even sure what to search for.
This is because you specified ValueFromPipeline=$True so that PoSh coerces the piped object to a string if it cannot bind the parameter by property name. You could solve that by removing ValueFromPipeline=$True from this parameter and introduce another one to be bound to the piped object, i.e. something like this
function MyTestFunc() {
param(
[Parameter(ValueFromPipeline=$True)]
[object]$PipedObj,
[Parameter(Mandatory=$False,
ValueFromPipelinebyPropertyName=$True,
HelpMessage="TCP Port of the remote server")]
[Alias('Port', 'Remote Server Port')]
[string]$RemoteServerPort = "5500"
)
Write-Host "Port: $RemoteServerPort / Obj: $PipedObj"
}
$o1 = [pscustomobject]#{"Server" = "123"; "Port" = "12345"}
$o2 = [pscustomobject]#{"Server" = "1234"; "OS" = "Win3.1"}
$o1 | MyTestFunc
$o2 | MyTestFunc
Will result in
Port: 12345 / Obj: #{Server=123; Port=12345}
Port: 5500 / Obj: #{Server=1234; OS=Win3.1}
A way to see in detail what is actually happening behind the scenes is to use Trace-Command like so
Trace-Command ParameterBinding {$o2 | MyTestFunc} -PSHost
I've got some strange behavior between me running a command under my profile, and TeamCity running the same command.
> Import-Module $root\packages\fsm.buildrelease.*\tools\modules\BuildDeployModules -Force
If I run the script manually, the build kicks off as expected. If I let TeamCity execute the script, it pukes with the following.
Import-Module : The specified module 'C:\BuildAgent\work\81eb7c2fdfcfc0af\packages\fsm.buildrelease.*\tools\modules\BuildDeployModules' was not loaded because no valid module file was found in any module directory.
I have double and triple verified that the module exists in that location. And I've gone through my modules and added [cmdletbinding()] before the param, but it doesn't seem to solve this issue.
It's frustrating because it doesn't say "which" module is getting an invalid parameter passed in.
$fsmbrVersion = "1.1.1" # contains the current version of fsm.buildrelease
Write-Host "`nfsm.buildrelease version $fsmbrVersion `nCopyright ($([char]0x00A9)) Future State Mobile Inc. & Contributors`n"
Push-Location $psScriptRoot
. .\Add-HostsFileEntry.ps1
. .\Add-IISHttpVerb.ps1
. .\Add-IISMimeType.ps1
. .\Add-LoopbackFix.ps1
. .\ApplicationAdministration.ps1
. .\AppPoolAdministration.ps1
. .\Approve-Permissions.ps1
. .\Assert-PSVersion.ps1
. .\EntityFramework.ps1
. .\Expand-NugetPackage.ps1
. .\Expand-ZipFile.ps1
. .\Format-TaskNameToHost.ps1
. .\Get-EnvironmentSettings.ps1
. .\Grunt.ps1
. .\Helpers.ps1
. .\Install-WebApplication.ps1
. .\Invoke-Deployment.ps1
. .\Invoke-DeployOctopusNugetPackage.ps1
. .\Invoke-ElevatedCommand.ps1
. .\Invoke-ExternalCommand.ps1
. .\Invoke-Using.ps1
. .\MSBuild.ps1
. .\Nuget.ps1
. .\nUnit.ps1
. .\Set-IISAuthentication.ps1
. .\Set-IISCustomHeader.ps1
. .\SiteAdministration.ps1
. .\Specflow.ps1
. .\SqlHelpers.ps1
. .\Test-PathExtended.ps1
. .\Test-RunAsAdmin.ps1
. .\TextUtils.ps1
. .\Update-AssemblyVersions.ps1
. .\Update-JsonConfigFile.ps1
. .\Update-XmlConfigFile.ps1
. .\WindowsFeatures.ps1
. .\xUnit.ps1
Pop-Location
Export-ModuleMember `
-Alias #(
'*') `
-Function #(
'Add-HostsFileEntry',
'Add-IISHttpVerb',
'Add-IISMimeType',
'Add-LoopbackFix',
'Approve-Permissions',
'Assert-That',
'Assert-PSVersion',
'Confirm-ApplicationExists',
'Confirm-AppPoolExists',
'Confirm-SiteExists',
'Exec',
'Expand-NugetPackage',
'Expand-ZipFile',
'Format-TaskNameToHost',
'Get-Application',
'Get-Applications',
'Get-AppPool',
'Get-AppPools',
'Get-DatabaseConnection',
'Get-EnvironmentSettings',
'Get-Site',
'Get-Sites',
'Get-TestFileName',
'Get-WarningsFromMSBuildLog',
'Get-WindowsFeatures',
'Install-WebApplication',
'Install-WindowsFeatures',
'Invoke-BulkCopy',
'Invoke-DBMigration',
'Invoke-Deployment',
'Invoke-DeployOctopusNugetPackage',
'Invoke-ElevatedCommand',
'Invoke-EntityFrameworkMigrations',
'Invoke-ExternalCommand',
'Invoke-FromBase64',
'Invoke-GruntMinification',
'Invoke-HtmlDecode',
'Invoke-HtmlEncode',
'Invoke-KarmaTests',
'Invoke-MSBuild',
'Invoke-Nunit',
'Invoke-NUnitWithCoverage'
'Invoke-SpecFlow',
'Invoke-SqlFile',
'Invoke-SqlStatement',
'Invoke-ToBase64',
'Invoke-UrlDecode',
'Invoke-UrlEncode',
'Invoke-Using',
'Invoke-XUnit',
'Invoke-XUnitWithCoverage',
'New-Application',
'New-AppPool',
'New-NugetPackage',
'New-Site',
'Remove-Application',
'Remove-AppPool',
'Remove-Site',
'RequiredFeatures',
'Set-IISAuthentication',
'Set-IISCustomHeader',
'Start-Application',
'Start-AppPool',
'Start-Site',
'Step',
'Stop-Application',
'Stop-AppPool',
'Stop-Site',
'Test-PathExtended',
'Test-RunAsAdmin',
'Update-Application',
'Update-AppPool',
'Update-AssemblyVersions',
'Update-JsonConfigValues',
'Update-Site',
'Update-XmlConfigValues'
)
# Messages
DATA msgs {
convertfrom-stringdata #"
error_duplicate_step_name = Step {0} has already been defined.
error_must_supply_a_feature = You must supply at least one Windows Feature.
error_feature_set_invalid = The argument `"{0}`" does not belong to the set `"{1}`".
error_admin_required = You are required to 'Run as Administrator' when running this deployment.
error_loading_sql_file = Error loading '{0}'. {1}.
error_octopus_deploy_failed = Failed to deploy: {0}.
error_specflow_failed = Publishing specflow results for '{0}' failed.
error_coverage_failed = Running code coverage for '{0}' failed.
error_tests_failed = Running tests '{0}' failed.
error_msbuild_compile = Error compiling '{0}'.
wrn_full_permission = You have applied FULL permission to '{0}' for '{1}'. THIS IS DANGEROUS!
wrn_cant_find = Could not find {0} with the name: {0}.
msg_grant_permission = Granting {0} permissions to {1} for {2}.
msg_enabling_windows_feature = Enabling Windows Feature: `"{0}`".
msg_wasnt_found = `"{0}`" wasn't found.
msg_updated_to = Updated `"{0}`" to `"{1}`".
msg_updating_to = Updating `"{0}`" to `"{1}`".
msg_changing_to = Changing `"{0}`" to `"{1}`".
msg_overriding_to = Overriding node `"{0}`" with value `"{1}`".
msg_updating_assembly = Updating AssemblyVersion to '{0}'. Updating AssemblyFileVersion to '{1}'. Updating AssemblyInformationalVersion to '{2}'.
msg_not_updating = Not updating {0}, you must specify the '-updateIfFound' if you wish to update the {0} settings.
msg_custom_header = Setting custom header '{0}' on site '{1}' to value '{2}'.
msg_disable_anon_auth = Disabling Anonymous Authentication for '{0}'.
msg_web_app_success = Successfully deploy Web Application '{0}'.
msg_copying_content = Copying {0} content to {1}.
msg_use_machine_environment = Using config for machine {0} instead of the {1} environment.
msg_octopus_overrides = Checking for Octopus Overrides for environment '{0}'.
msg_teamcity_importdata = ##teamcity[importData type='{0}' tool='{1}' path='{2}']
msg_teamcity_buildstatus = ##teamcity[buildStatus text='{0}']
msg_teamcity_buildstatisticvalue = ##teamcity[buildStatisticValue key='{0}' value='{1}']
msg_add_loopback_fix = Adding loopback fix for '{0}'.
msg_add_mime_type = Adding mime type '{0}' for extension '{1}' to IIS site '{2}'.
msg_add_verb = Adding IIS Http Verb '{0}' to site '{1}'.
msg_add_host_entry = Adding host entry for '{0}' into the hosts file.
msg_validate_host_entry = Validating host entry for '{0} in the hosts file'
msg_loopback_note = note: we're not disabling the loopback check all together, we are simply adding '{0}' to an allowed list.
"#
}
The problem is nothing to do with importing the module; powershell isn't very helpful in leading you to the issue. The root of the issue didn't reveal it's self until I put the -VERBOSE switch on the import. Once I did that, I got a new error above the old one.
: Parameter attributes need to be a constant or a script block.
FullyQualifiedErrorId: ParameterAttributeArgumentNeedsToBeConstandOrScriptBlock
Essentially, I was using ValidatePattern with double quotes instead of single quotes. Check and make sure your writing your regex patterns correctly when you use ValidatePattern
# Bad
[ValidatePattern("^[a-z]$")]
# Good
[ValidatePattern('^[a-z]$')]
I'm calling a powershell script like so, from within another script.
function test_execute_sql_2_direct_query()
{
& C:\Server\Scripts\PowerShellDeploy\Execute-SQL-Command.ps1 -SERVER_NAME "myserver" -SQL_COMMAND_TYPE "input" -SQL_FILE ".\select.sql" -USER_NAME "username" -PASSWORD "password" -DATABASE "accounts"
}
When I call that function I get an error message from Powershell that says 'Cannot validate argument on parameter 'Query'. The argument is null or empty....'
I don't quite follow why I'm getting that message? The Execute-SQL-Command script doesn't have an argument called 'Query'. Quite possible I'm missing something.
Here's its paramenter section:
param(
[Parameter(
HelpMessage="Server Name")]
[string]$SERVER_NAME = "",
[Parameter(
HelpMessage="Database")]
[string]$DATABASE = "",
[Parameter(
HelpMessage="Path to .SQL File to run. Used in input file mode (not direct query mode)")]
[string]$SQL_FILE ="",
[Parameter(
HelpMessage="Server Port (default = 1433)")]
[string]$SERVER_PORT = "1433",
[Parameter(
HelpMessage="Server Transport (default = tcp")]
[string]$TRANSPORT = "tcp",
[Parameter(
HelpMessage="Method of connecting to database <passthrough, credentialed>")]
[string]$CONNECT_METHOD = "passthrough",
[Parameter(
HelpMessage="Username -- used only for credentialed login")]
[string]$USER_NAME = "username",
[Parameter(
HelpMessage="Command type-- direct query or input file (.sql)")]
[string]$SQL_COMMAND_TYPE = "DIRECT_QUERY",
[Parameter(
HelpMessage="SQL statement text type-- used in direct queries")]
[string]$SQL_STATEMENT = "",
[Parameter(
HelpMessage="Password -- used only for credentialed login")]
[string]$PASSWORD = "pwd")
This one is chalked up to user error-- the actual error was coming from within a line called in Execute-SQL-Command.ps1-- specifically, the Invoke-Sqlcmd cmdlet.