calling a function with parameters

just starting out creating functions inside scripts…

script Script.ps1 contains a function called Function, which has two parameters. I want to call Function at the end of Script.ps1, so someone can run

.c:\script.ps1 parameter1 parameter2

and have it pass those two parameters to Function. but this doesn’t seem to be working. should I just not use a function, and have the script be autonomous, or is there a way to write it so I can pass parameters into Script1 so they get passed to Function?

Scripts can have the same parameter block that a function can. Parameters passed to a script are only given to the script; they don’t automatically flow thorugh to a function.

You’d need to define a parameter block for the script which accepts (at a minumum) the same parameters you want to pass to the function. For example:

# Param block at the beginning of the script

[CmdletBinding()]
param (
    $Parameter1,
    $Parameter2
)

# function definition in script with same (or subset) of the script's parameters
function Do-Something
{
    [CmdletBinding()]
    param (
        $Parameter1,
        $Parameter2
    )

    "$Parameter1, $Parameter2"
}

# Call the function, passing on the parameters that were given to the script

Do-Something -Parameter1 $Parameter1 -Parameter2 $Parameter2

thanks guys. now, what if one of the parameters in the function is a switch? just use if-else logic when I call the function at the end of the script?

When you declare a parameter as type [switch], PowerShell will set the corresponding variable to $True or $False inside the function. You either include the parameter when running the function, or you don’t - just like with -Force on Remove-ChildItem, or -Recurse on Get-ChildItem.

You can also pass an explicit value to a switch:

Do-Something -Switch:$true

If that’s an easier way of passing the value you want. Finally, it’s possible to use splatting, which lets you assemble a hash table of parameters and values. That way, you can programmatically add, or not add, a switch parameter to the hash table before calling the function.

here is the bare script, with no function defined. I pass it a server FQDN and the -qa switch, which determines the management group the $serverfqdn gets its SCOM agent installed.

param(
[switch]$QA,
[parameter(mandatory=$true)][string]$ServerFQDN
)

if ($QA) {$mgmtservername=“sismgrq1”}
else {$mgmtservername=“sismgrp1”}

invoke-command -computername $MGMTservername -scriptblock {
import-module OperationsManager
$ManagementServer= Get-SCOMManagementServer | where {$_.Name -like “*$($args[1])”}
Install-SCOMAgent -PrimaryManagementServer $ManagementServer -DNSHostName $($args[0])
} -argumentlist $ServerFQDN,$mgmtservername

so running ".\script.ps1 -qa server.domain.com " installs a scom agent on server.domain.com, pointing at the QA SCOM server sismgrq1.

honestly this works fine for my purposes, but after attending, you know, certain teched 2014 sessions, I’m trying to learn to use functions and cmdletbinding and all that good stuff (step 2, after sheepishly removing a… ahem, handful of write-hosts from my scripts.)

so, wrapping this in a function, I came up with

param(
[switch]$QA,
[parameter(mandatory=$true)][string]$ServerFQDN
)

function install-scom-agent
{
[CmdletBinding()]
param(
[switch]$QA,
[parameter(mandatory=$true)][string]$ServerFQDN
)

if ($QA) {$mgmtservername=“sismgrq1”}
else {$mgmtservername=“sismgrp1”}

invoke-command -computername $MGMTserverName -scriptblock {
import-module OperationsManager
$ManagementServer= Get-SCOMManagementServer | where {$_.Name -like “*$($args[1])”}
Install-SCOMAgent -PrimaryManagementServer $ManagementServer -DNSHostName $($args[0])
} -argumentlist $ServerFQDN,$mgmtservername

}

if ($qa){install-scom-agent -QA $ServerFQDN}
else {install-scom-agent $ServerFQDN}

but that looks clunky even to me, especially with “if ($QA)” statements both inside the function and out…