0

I have a PowerShell script that contains several functions. One of the functions should receive command line arguments. Here's a similar script to what I'm doing:

$mydocs = [Environment]::GetFolderPath("MyDocuments")

function example() {
  Param(
    [string]$name = "testfolder", 
    [switch]$foo = $false
  )
  $newdir = $mydocs + "\" + $name
  if (!(Test-Path $newdir)) { mkdir $newdir }
}
example

So when I run this:

.\example.ps1 -name anewfolder -foo

I want the function example to use these arguments.

Because of scoping, my function has no $args. I put Write-Host $args into the function to double check, and it returns nothing. How can I pull the parent args, pass them into params, and get example to run with my arguments? Or should I just remove the function and run this part of my code in the parent scope?

1
  • To do it this way, you'd have to add the same param() set to the top of your script and then call the function (as you are doing) with the params specified. Commented Oct 24, 2017 at 21:18

2 Answers 2

1

If you want to pass arguments to your script, you need to capture them in a Param() block like your Function has. Alternatively, you can access script args with a scope selector like $script:Args.

Param([String]$Name,[Switch]$Foo)

$mydocs = [Environment]::GetFolderPath("MyDocuments")

function example
{
  param(
    [string]$name, 
    [switch]$foo
  )
  $newdir = Join-Path $mydocs $name
  if (!(Test-Path $newdir)) { mkdir $newdir }
}
example -Name $Name -Foo

Now, .\example.ps1 -name anewfolder -foo will be successful.

Sign up to request clarification or add additional context in comments.

1 Comment

This answer is not correct. The questioner wants the function to use the arguments that are passed into the script. Your answer just hard codes the value for $foo. If you call the script as ".\example.ps1 -name anewfolder", the function will still see $foo as $true.
1

$args inside the function is a different variable than $args in the global scope of the script. A very simple way of passing arbitrary script arguments to your function is to splat $args:

example @args

Note, however, that this isn't a very clean approach. It'd be better to properly parameterize the script and selectively pass those parameters that are meant to go to the function, as TheIncorrigible1 suggested.

Param(
    [string]$name,
    [int]$bar,
    [switch]$foo
)

function example() {
    Param(
        [string]$name = "testfolder", 
        [switch]$foo
    )

    $newdir = "${mydocs}\${name}"
    if (!(Test-Path $newdir)) { mkdir $newdir }
}

$params = @{}
if ($PSBoundParameters.ContainsKey('name')) { $params['name'] = $name }
if ($PSBoundParameters.ContainsKey('foo'))  { $params['foo']  = $true }

example @params

2 Comments

In contrast to @TheIncorrigible1, your answer is correct. But I wish there was a simpler way, similar to his answer, which would correctly pass not only $name but the switch $foo.
@JohnPankowicz Well, you could simply do example @PSBoundParameters, but that would pass through all parameters given to the script, not just the ones that are valid for the function. Meaning a parameter -bar 42 would also be passed to the function, which may or may not cause problems, depending on the rest of the code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.