I want my Powershell script to be able to handle two parameter sets as shown below.
Set 1:
Param1: GroupName via pipe
Param2: FilePath
Called like: "GROUPNAME" | script.ps1 FilePath
Set 2:
Param1: GroupName
Param2: FilePath
Called like: script.ps1 GroupName FilePath
In both cases both arguments are mandatory.
I have tried everything I can think of and the closest I think I have gotten is this:
[CmdletBinding(DefaultParameterSetName="Pipe")]
param (
[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$false,HelpMessage="AD Group Name",ParameterSetName="Param")]
[Parameter(Mandatory=$true,ValueFromPipeline=$true,HelpMessage="AD Group Name",ParameterSetName="Pipe")]
[ValidateNotNullOrEmpty()]
[String]$GroupName,
[Parameter(Mandatory=$true,Position=1,ValueFromPipeline=$false,HelpMessage="Path to CSV",ParameterSetName="Param")]
[Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$false,HelpMessage="Path to CSV",ParameterSetName="Pipe")]
[ValidateNotNullOrEmpty()]
[String]$FilePath
)
This does not work, as it always expect the second argument at position 1; any ideas?
You don't need two parameter sets. ValueFromPipeline=$true makes the function accept input from the pipeline, but doesn't require that it come from the pipeline - it can be specified as an argument just as well.
Related
In second-instance, I want to receive data with double URL like
The actual operation effect is as follows
there is a solution in github https://github.com/electron/electron/issues/34195
But it needs an extra parameter --
I can't do it by electron.lnk
Every time I open the program with cmd, I can't add this parameter.
Is there any way to implement it through code.
actual parameters
[
"electron.exe",
"--allow-file-access-from-files",
"https://github.com/1",
"https://github.com/2",
"3"
]
I tried below method but it didn't work
const args = []
args.push('--')
app.setAsDefaultProtocolClient(PROTOCOL, process.execPath, args)
i'm trying to write a Nmap NSE DNS bruteforce script for a school work.
my problem is that when using the function : dns.query(dname,options)
where dname is a FQDN, the result is different is the argument is
1: A hardcoded string like this
local status, result = dns.query("www.domain.com", {dtype="A",retAll=true})
or 2: a variable made in the function match that concatenates two strings
local status, result = dns.query(domain, {dtype="A",retAll=true})
local function match(sub,host)
local domain = print(sub.."."..host.name)
local status, result = dns.query(domain, {dtype="A",retAll=true})
if status == "true" then
return domain
end
return ''
end
debug mode shows that the variable domain is indeed equal to the same value as the hardcoded string. But the behavior is different.
what could cause this sort of problem ?
docs for dns library : https://nmap.org/nsedoc/lib/dns.html
I'm trying to write a Jenkins plugin that provides Step myStep which expects a block with a single parameter per below
myStep { someParameter -> <user code> }
I've found that BodyInvoker ( retrieved from StepContext.newBodyInvoker() ) provides no facilities to invoke the user provided block with parameters.
Expanding the environment would not be ideal, even though the type of the parameter is serializable ( to/from String ), i'd have to provide additional helpers to carry out this serialization, e.g
myStep { deserialize "${env.value}" <user code> }
do i have any other option to pass a non-string type in to the provided block? would type information of the parameter survive even if i did?
nb: i understand you can return a value from your Execution.run() which will be the return value of the step in the pipeline. It's just that in a related shared pipeline library i'm already heavily leaning in to this pattern of:
withFoo { computedFoo ->
# something with computedFoo
withBar computedFoo { computedBar ->
}
}
i prefer this over
computedFoo = withFoo
# something with computedFoo
withBar(computedFoo)
..then again, i couldn't find any plugins pulling this off.
no matter how close i look at workflow-step-api-plugin this doesn't seem possible today. The options are:
expand the environment context with a string value
add a custom object to the context ( requires access to step context in pipeline )
use a return value
I'm setting a Jenkins pipeline Jenkinsfile and I'd like to check if a booleanparameter is set.
Here's the relevant portion of the file:
node ("master") {
stage 'Setup' (
[[$class: 'BooleanParameterValue', name: 'BUILD_SNAPSHOT', value: 'Boolean.valueOf(BUILD_SNAPSHOT)']],
As I understand, that is the way to access the booleanparameter but I'm not sure how to state the IF statement itself.
I was thinking about doing something like:
if(BooleanParameterValue['BUILD_SNAPSHOT']){...
What is the correct way to write this statement please?
A boolean parameter is accessible to your pipeline script in 3 ways:
As a bare parameter, e.g: isFoo
From the env map, e.g: env.isFoo
From the params map, e.g: params.isFoo
If you access isFoo using 1) or 2) it will have a String value (of either "true" or "false").
If you access isFoo using 3) it will have a Boolean value.
So the least confusing way (IMO) to test the isFoo parameter in your script is like this:
if (params.isFoo) {
....
}
Alternatively you can test it like this:
if (isFoo.toBoolean()) {
....
}
or
if (env.isFoo.toBoolean()) {
....
}
the toBoolean() is required to convert the "true" String to a boolean true and the "false" String to a boolean false.
The answer is actually way simpler than that !
According to the pipeline documention, if you define a boolean parameter isFoo you can access it in your Groovy with just its name, so your script would actually look like :
node {
stage 'Setup'
echo "${isFoo}" // Usage inside a string
if(isFoo) { // Very simple "if" usage
echo "Param isFoo is true"
...
}
}
And by the way, you probably should'nt call your parameter BUILD_SNAPSHOT but maybe buildSnapshot or isBuildSnapshot because it is a parameter and not a constant.
simply doing if(isFoo){...} that will not guarantee it working :) To be safe, use if(isFoo.toString()=='true'){ ... }
I have a script like this:
param(
[Alias('a')]
[string]$aval,
[Alias('b')]
[switch]$bval,
[Alias('c')]
[string]$cval
)
if($aval.length -gt 1)
{
Do-Something
}
elseif($bval)
{
Do-Something-Else
}
elseif($cval.length -gt 1)
{
Do-Another-Thing
}
else
{
Do-This
}
If someone calls my script like so, an ugly error is displayed saying it is missing an argument for parameter 'aval/bval/cval':
PS C:\> .\MyScript.ps1 -a
C:\MyScript.ps1 : Missing an argument for parameter 'aval'. Specify a
parameter of type 'System.String' and try again.
At line:1 char:18
+ .\MyScript.ps1 -n <<<<
+ CategoryInfo : InvalidArgument: (:) [MyScript.ps1], ParameterBindingException
+ FullyQualifiedErrorId : MissingArgument,MyScript.ps1
Is there any way to make a cleaner, possibly one line, error appear instead? Also, is there a better way to handle parameters then a list of elseif statements (my actual script has ~10 parameters)?
The script sometimes passes an argument with a parameter as well:
EX:
PS C:\> .\MyScript.ps1 -b ServerName
Thanks for any help!
There are a few things that you can look at here. First, if the parameter will never have an associated value and you just want to know if the script was called with the parameter or not, then use a [switch] parameter instead of a string.
Here is a very simple example of using a switch parameter:
param(
[switch]$a
)
if($a){
'Switch was present'
}else{
'No switch present'
}
Save that as a script and run it with and without the -a parameter.
If you will sometimes have the parameter present with some value being passed in but other times without the value, then give the parameter a default value when you define it:
[Alias('a')]
[string]$aval = '',
Then in your logic if something was passed in, the length of the string will be gt 1.
As for the if-then structure that you have, there are a plethora of options for handling this sort of logic. with the little bit of information that you have shared, I suspect that using switch structure will be the best plan:
Get-Help about_Switch