Powershell - A parameter cannot be found that matches parameter name - powershell

Something small I'm missing obviously, but I've followed several PS tutorials and I'm still getting the error.
I have a small PS script that I want to pass an argument to, this is to be eventually used in an Azure DevOps pipeline, but I can't even get this to work locally.
[CmdletBinding()]
param (
$EnvironmentName
)
$env = $EnvironmentName
Write-Host "$env"
Invoked with: ps HealthCheck.ps1 -EnvironmentName DEV
I keep getting the error
Get-Process : A parameter cannot be found that matches parameter name 'EnvironmentName'.
At line:1 char:20
+ ps HealthCheck.ps1 -EnvironmentName DEV

Related

Powershell - rerun the script with different credentials from itself

I have currently had to take a huge leap from my unix scripting to the MS side of things and found myself overwhelmed with PowerShell.
My situation is as follows:
I have a script script.ps1 which can be only run under specific windows account. In order to facilitate the use, it was decided that if user runs the script from a different account, it will pop up a query for credentials and restart itself from within (similarly to recursion), but importantly - maintaining the input parameters.
I have found out, that the Invoke-Command is probably what I am looking for, but I cannot seem to be able to build the PS query for this.
my code snippet looks like
if(!([System.Environment]::UserName -eq $user)){
$Credential = Get-Credential -credential INTRANET\$user
Invoke-Command -FilePath $script -Credential $Credential -ArgumentList $arguments
}
where $user contains the desired user, $script contains filepath to the script.ps1 and $arguments contain command line arguments that were passed to the script as a String, i. e. -order 66 -location UAT
but currently I get an error
Parameter set cannot be resolved using the specified named parameters.
...
FullyQualifiedErrorId : AmbiguousParameterSet
I tried shuffling the parameters around, I tried using Start-Process instead of Invoke-Command, but everything resulted in same or similar errors.
Also, because I am really new to the powershell, please do not hesitate to offer different solution, if it is viable. I do not know the capabilities of the language well.
Lastly, please note that the starting point is always powershell prompt running with non-elevated user account. Unfortunately, the option to start up powershell under a different account in the first place is not available to us.
The problem probably is that you specify the parameters stored in the variable $arguments as string in the regular format like you said: -order 66 -location UAT
The parameter -ArgumentList works differently, its an array used for array splatting. So you can't pass the values by the parameter name. You have to pass the values by parameter order, e.g.:
$Arguments = #(66,'uat')
Invoke-Command -FilePath $script -Credential $Credential -ArgumentList $Arguments
See Parameter Argumentlist.
See Array Splatting.
The value 66 is passed to the first parameter, the value uat to the 2nd... So you must know the order of the parameters and insert the related values into the array at the right position.
To control the position of the parameters, the param specification in the other script should at least have:
param (
[parameter(Position=1)]
[int]$order,
[parameter(Position=2)]
[string]$location
)

Unable to pass hashtable of parameters to another script using Invoke-Command

I've built a script for dynamically changing an HTML template and sending it as an email, it uses a hashtable for the items to be changed due to a fluctuating number of items it may need to change (seemed a better option than an array)
The emailing and replacing of variables etc is all working correctly, where I'm having issues is when I try to call it from another script and pass in a hashtable with the replacements and to/fromsubject, I'm using Splatting as it seemed the best option, I have tried just passing in the hashtable as is, and tried start-job and Invoke-Expression
powershell version: 5.1
This is the code I'm using to call the emailing script
$TemplateReplacements = #{}
$TemplateReplacements.Add("EmailTo","firstname.lastname#company.com.au")
$TemplateReplacements.Add("EmailFrom","ISnotifications#company.com.au")
$TemplateReplacements.Add("EmailSubject","Test Test Test")
$TemplateReplacements.Add("EmailTemplate","\ZeroLicenses.html")
$TemplateReplacements.Add("Heading","Heading replaced from main script")
$TemplateReplacements.Add("1","Variable1 repalced from main script")
$TemplateReplacements.Add("2","Variable2 replaced from main script")
$TemplateReplacements.Add("3","Variable3 replaced from main script")
$TemplateReplacements.Add("4","Variable4 replaced from main script")
$ScriptToRun = "C:\Users\User1\Desktop\Projects\Powershell\EmailVarReplace-Test\Test3.ps1"
$params = #{
Replacements = $TemplateReplacements
}
Invoke-Command $ScriptToRun #Params
#start-job $ScriptToRun #params
In the email script thats been called I have this at the top hich I believe is all I need for it to accept the parameter?
[CmdletBinding()]
param ($Replacements)
I've been stumped on this for ages and just keep getting the error
Invoke-Command : A parameter cannot be found that matches parameter name 'Replacements'.
At C:\Users\User1\Desktop\Projects\Powershell\EmailTest.ps1:19 char:29
+ Invoke-Command $ScriptToRun #Params
+ ~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Invoke-Command], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.InvokeCommandCommand
What I'm expecting to happen is it passes the hashtable into the script so it can get the variables for where to send the email to, what address from, subject plus the replacements of variables in the email
I'm building the email script as a standalone module that later just needs templates created adn scripts calling it with the replacements made
Any help would be very appreciated
Also ignore the hard-coded path etc as it's still a testing script :p
Don't use Invoke-Command to invoke your script - Invoke-Command is virtually only ever useful in the context of remoting, i.e. if you use with the -ComputerName parameter to run a script of script block on one or more remote computers.
Instead, use &, the call operator, to invoke your script, then splatting should work as intended:
& $ScriptToRun #Params
As for what you tried:
If you try splatting via Invoke-Command, the splatting is applied to its parameters, not to the parameters of the script you're invoking.
Therefore, a -Replacements parameter is looked for among Invoke-Command's parameters rather than your script's - and there is no such parameter, which explains the error you got.

Register-Environment Failing

I am having trouble creating a release definition on Azure DevOps. I believe the Register-Environment function in PowerShellOnTargetMachines.ps1 is failing:
try
{
$connection = Get-VssConnection -TaskContext $distributedTaskContext
Write-Verbose "Starting Register-Environment cmdlet call for environment : $environmentName with filter $machineFilter"
$environment = Register-Environment -EnvironmentName $environmentName -EnvironmentSpecification $environmentName -UserName $adminUserName -Password $adminPassword -WinRmProtocol $protocol -TestCertificate ($testCertificate -eq "true") -Connection $connection -TaskContext $distributedTaskContext -ResourceFilter $machineFilter
Write-Verbose "Completed Register-Environment cmdlet call for environment : $environmentName"
Write-Verbose "Starting Get-EnvironmentResources cmdlet call on environment name: $environmentName"
$resources = Get-EnvironmentResources -Environment $environment
if ($resources.Count -eq 0)
{
Write-Telemetry "Input_Validation" "No machine exists for given environment"
throw (Get-LocalizedString -Key "No machine exists under environment: '{0}' for deployment" -ArgumentList $environmentName)
}
$resourcesPropertyBag = Get-ResourcesProperties -resources $resources
}
With the following error (I have omitted some of my organization's information, but it is there and looks right):
2019-09-04T12:34:55.6886629Z ##[debug]VssConnection created
2019-09-04T12:34:55.7518340Z ##[debug]Starting Register-Environment cmdlet call for environment : [machine] with filter [machine]
2019-09-04T12:34:55.7843531Z ##[debug]Begin Create-Environment cmdlet
2019-09-04T12:34:55.7872731Z ##[debug]UserName=[username]
2019-09-04T12:34:55.7878292Z ##[debug]WinRmProtocol=HTTP
2019-09-04T12:34:55.7878658Z ##[debug]TestCertificate=False
2019-09-04T12:34:55.7878965Z ##[debug]Unable to create a environment object for given json - Unexpected character encountered while parsing value: A. Path '', line 0, position 0.
2019-09-04T12:34:55.7879241Z ##[debug]projectName=[projectName]
2019-09-04T12:34:55.7879517Z ##[debug]Getting environment [machine] from DTL Service
2019-09-04T12:34:55.8485808Z ##[debug]Processed: ##vso[task.logissue type=error;code={"Task_Internal_Error":Page not found.};]
And I do not know what to do. Any ideas are appreciated. Thanks for taking the time to read my question.
Based on the details which from comment that Mike left, the issue should caused by the the task version you are using and its feature script we defined.
According to the ticket description you raised in DC ticket:
I am trying to use V2 of the following 'PowerShellOnTargetMachines'
PowerShell script for a release on azure devops, from
azure-pipeline-tasks.
the version of PowerShellOnTargetMachines you are using is 2.*.
We can get the Register-Environment cmdlet script with decompile tool follow the method I showed in this case.
You can see the parameters this cmdlet supported in 'PowerShellOnTargetMachines V2.*' does not include TaskContext and Connection. That's why you receive the error message "Unable to create a environment object for given json - Unexpected character encountered while parsing value". Because the parameter you input in the task does not match the configuration of Register-Environment cmdlet.
You can try with PowerShellOnTargetMachines V1.*. In 1.* we support the parameters TaskContext and Connection.

VSTS Release error: A parameter cannot be found that matches parameter name 'Server'

I have a PowerShell script that contains this at the top:
Param(
# [snip]
[string] [Parameter(Mandatory=$true)] $Server
)
In my VSTS Release definition, I added an Azure Powershell task calling the script, and passed the argument as:
-Server '$(ServerName)' [snip]
However, when I trigger a new Release, at the step for this script, I get this error:
##[error]A parameter cannot be found that matches parameter name 'Server'.
I verified in the log output that the server name is passed properly. I even copy/pasted the command logged, and after fixing paths, it ran locally with no problems.
Why is this happening, and how can I fix it?
Changing the name of the argument fixed the issue. My script now contains:
Param(
# [snip]
[string] [Parameter(Mandatory=$true)] $ServerName
)
And I pass the arguments as:
-ServerName '$(ServerName)' [snip]
As for the why, I can only speculate. I checked the source code but couldn't find anything obvious. My only guess is that the Azure PowerShell task overwrote $Server for some reason (though I'm not sure why the log output would show the correct argument in that case).
Your $Server variable is already declared. I give you some trick when you want to test code or something like this. First remove variable and clear screen like this example:
cls
Remove-Variable server
function ssssss
{
param
(
[string][parameter(Mandatory = $true)]$server
)
Write-Host $server
}
ssssss -server "Enter servername here"
It's working fine.
For me the error was the way I was passing the arguments to the task,
When I passed all in one line it actually worked

Using [ValidateScript] in Param results in error about already declared parameter

I have the following Param block at the start of my script:
Param
(
[Parameter(Mandatory = $true)]
[ValidateScript({Test-Path $_ -PathType Leaf})]
[string]$Config,
[switch]$OverThresholdOnly,
[switch]$SendEmail,
[switch]$Debug
)
When I run the script I get the error:
"A parameter with the name 'Debug' was defined multiple times for this command. At line:1 char:1"
Line:1 and char:1 is the start of the Param block.
If I change the $Debug to $Verbose I get the same error about Verbose. I've tried putting the $debug at the top of the Param block with the same error.
If I remove the [ValidateScript] section it works fine.
Can anybody tell me why it does this? Why [ValidateScript] is using $Debug and how to get around this short of renaming the variable?
PowerShell has ubiquitous parameters which exist for every cmdlet.
Check out get-help about_common_parameters or click here.
-Debug and -Verbose are two of the common parameters. Chose a different name to avoid the naming collision.
When you add the parameter attribute it changes the way PowerShell treats the parameters. It becomes an advanced function at that point a.k.a a script cmdlet. Script cmdlets receive the common parameters automatically.
Check out get-help about_Functions_Advanced or click here
And get-help about_Functions_Advanced_Parameters or click here