608

There's a PowerShell script named itunesForward.ps1 that makes iTunes fast forward 30 seconds:

$iTunes = New-Object -ComObject iTunes.Application

if ($iTunes.playerstate -eq 1)
{
  $iTunes.PlayerPosition = $iTunes.PlayerPosition + 30
}

It is executed with a prompt line command:

powershell.exe itunesForward.ps1

Is it possible to pass an argument from the command line and have it applied in the script instead of the hardcoded 30 seconds value?

0

8 Answers 8

804

Tested as working:

#Must be the first statement in your script (not counting comments)
param([Int32]$step=30) 

$iTunes = New-Object -ComObject iTunes.Application

if ($iTunes.playerstate -eq 1)
{
  $iTunes.PlayerPosition = $iTunes.PlayerPosition + $step
}

Call it with

powershell.exe -file itunesForward.ps1 -step 15

Multiple parameters syntax (comments are optional, but allowed):

<#
    Script description.

    Some notes.
#>
param (
    # height of largest column without top bar
    [int]$h = 4000,
    
    # name of the output image
    [string]$image = 'out.png'
)

And some example for advanced parameters, e.g. Mandatory:

<#
    Script description.

    Some notes.
#>
param (
    # height of largest column without top bar
    [Parameter(Mandatory=$true)]
    [int]$h,
    
    # name of the output image
    [string]$image = 'out.png'
)

Write-Host "$image $h"

A default value will not work with a mandatory parameter. You can omit the =$true for advanced parameters of type boolean [Parameter(Mandatory)].

14
  • 10
    what if the parameter is a string? What is the syntax? would it be something like -step '15' or -step "15" Commented Nov 2, 2015 at 0:04
  • 10
    @Andrew First of all you have to change the type of the parameter to [string]. If you then want to pass a string as parameter you can use either ' or ". If there is no space (or quotes) inside the string you can even omit the quotes. Commented Nov 2, 2015 at 8:31
  • 88
    FYI, to use multiple params, use this syntax: param([string]$env,[string]$s3BucketName) Commented Dec 29, 2015 at 23:12
  • 3
    It is missing "-file". It doesnt work for me until i added this. See the complete code: powershell.exe -file itunesForward.ps1 -step 15
    – Charles
    Commented Feb 22, 2016 at 23:43
  • 2
    @Charles Thanks for the hint. You are right: The -file is missing from the call. The call without might work with Powershell Version 1.0 but I can't test it. Updated the answer. Commented Feb 23, 2016 at 8:36
444

You can use also the $args variable (that's like position parameters):

$step = $args[0]

$iTunes = New-Object -ComObject iTunes.Application

if ($iTunes.playerstate -eq 1)
{
  $iTunes.PlayerPosition = $iTunes.PlayerPosition + $step
}

Then it can be called like:

powershell.exe -file itunersforward.ps1 15
4
  • 66
    Found this easier than the accepted solution, PLUS you can directly use $args[0] anywhere in the script (no need to be first line). PS: Tip on passing strings as arguments: They must be enclosed in single quotes.
    – ADTC
    Commented Jul 14, 2012 at 6:21
  • 37
    Both this and the accepted solution work, the main difference is that this reads parameters by position, while the accepted solution does it by name. When multiple parameters need to be passed, passing by name might be cleaner. Commented Nov 22, 2013 at 15:57
  • 6
    named params in accepted solution also auto populate get-help
    – Pete
    Commented Jul 21, 2015 at 19:21
  • 3
    This answer is getting so much attention, please check out the related one which is much more complete. stackoverflow.com/questions/6359618/… Commented Sep 1, 2016 at 13:55
44

Call the script from a batch file (*.bat) or CMD

PowerShell Core

pwsh.exe -NoLogo -ExecutionPolicy Bypass -Command "./Script.ps1 -Param1 Hello -Param2 World"

pwsh.exe -NoLogo -ExecutionPolicy Bypass -Command "path-to-script/Script.ps1 -Param1 Hello -Param2 World"

pwsh.exe -NoLogo -ExecutionPolicy Bypass -Command "./Script.ps1 Hello -Param2 World"

pwsh.exe -NoLogo -ExecutionPolicy Bypass -Command "./Script.ps1 Hello World"

pwsh.exe -NoLogo -ExecutionPolicy Bypass -Command "./Script.ps1 -Param2 World Hello"

PowerShell

powershell.exe -NoLogo -ExecutionPolicy Bypass -Command "./Script.ps1 -Param1 Hello -Param2 World"

powershell.exe -NoLogo -ExecutionPolicy Bypass -Command "path-to-script/Script.ps1 -Param1 Hello -Param2 World"

powershell.exe -NoLogo -ExecutionPolicy Bypass -Command "./Script.ps1 Hello -Param2 World"

powershell.exe -NoLogo -ExecutionPolicy Bypass -Command "./Script.ps1 Hello World"

powershell.exe -NoLogo -ExecutionPolicy Bypass -Command "./Script.ps1 -Param2 World Hello"

Call from PowerShell

PowerShell Core or Windows PowerShell

& path-to-script/Script.ps1 -Param1 Hello -Param2 World
& ./Script.ps1 -Param1 Hello -Param2 World

Script.ps1 - Script Code

param(
    [Parameter(Mandatory=$True, Position=0, ValueFromPipeline=$false)]
    [System.String]
    $Param1,

    [Parameter(Mandatory=$True, Position=1, ValueFromPipeline=$false)]
    [System.String]
    $Param2
)

Write-Host $Param1
Write-Host $Param2
2
  • Does the Position=0 setting turn it into a positional parameter rather than a flag?
    – FilBot3
    Commented Sep 5, 2020 at 12:04
  • 1
    if you don't use the parameter names, you need to send correct values respecting the positions. Check the update for this answer.
    – Joma
    Commented Sep 7, 2020 at 3:12
9

Let PowerShell analyze and decide the data type. It internally uses a 'Variant' for this.

And generally it does a good job...

param($x)
$iTunes = New-Object -ComObject iTunes.Application
if ($iTunes.playerstate -eq 1)
{
    $iTunes.PlayerPosition = $iTunes.PlayerPosition + $x
}

Or if you need to pass multiple parameters:

param($x1, $x2)
$iTunes = New-Object -ComObject iTunes.Application
if ($iTunes.playerstate -eq 1)
{
    $iTunes.PlayerPosition = $iTunes.PlayerPosition + $x1
    $iTunes.<AnyProperty>  = $x2
}
9
# ENTRY POINT MAIN()
Param(
    [Parameter(Mandatory=$True)]
    [String] $site,
    [Parameter(Mandatory=$True)]
    [String] $application,
    [Parameter(Mandatory=$True)]
    [String] $dir,
    [Parameter(Mandatory=$True)]
    [String] $applicationPool
)

# Create Web IIS Application
function ValidateWebSite ([String] $webSiteName)
{
    $iisWebSite = Get-Website -Name $webSiteName
    if($Null -eq $iisWebSite)
    {
        Write-Error -Message "Error: Web Site Name: $($webSiteName) not exists."  -Category ObjectNotFound
    }
    else
    {
        return 1
    }
}

# Get full path from IIS WebSite
function GetWebSiteDir ([String] $webSiteName)
{
    $iisWebSite = Get-Website -Name $webSiteName
    if($Null -eq $iisWebSite)
    {
        Write-Error -Message "Error: Web Site Name: $($webSiteName) not exists."  -Category ObjectNotFound
    }
    else
    {
        return $iisWebSite.PhysicalPath
    }
}

# Create Directory
function CreateDirectory([string]$fullPath)
{
    $existEvaluation = Test-Path $fullPath -PathType Any
    if($existEvaluation -eq $false)
    {
        new-item $fullPath -itemtype directory
    }
    return 1
}

function CreateApplicationWeb
{
    Param(
        [String] $WebSite,
        [String] $WebSitePath,
        [String] $application,
        [String] $applicationPath,
        [String] $applicationPool
        )
    $fullDir = "$($WebSitePath)\$($applicationPath)"
    CreateDirectory($fullDir)
    New-WebApplication -Site $WebSite -Name $application -PhysicalPath $fullDir -ApplicationPool $applicationPool -Force
}

$fullWebSiteDir = GetWebSiteDir($Site)f($null -ne $fullWebSiteDir)
{
    CreateApplicationWeb -WebSite $Site -WebSitePath $fullWebSiteDir -application $application  -applicationPath $dir -applicationPool $applicationPool
}
1
  • It's works .\create-application-pool.ps1 -site xx_8010 -application AppTest -dirtestDir -applicationPool TestAppPool Commented Feb 15, 2020 at 2:47
6

Create a PowerShell script with the following code in the file.

param([string]$path)
Get-ChildItem $path | Where-Object {$_.LinkType -eq 'SymbolicLink'} | select name, target

This creates a script with a path parameter. It will list all symbolic links within the path provided as well as the specified target of the symbolic link.

4

You can also define a variable directly in the PowerShell command line and then execute the script. The variable will be defined there, too. This helped me in a case where I couldn't modify a signed script.

Example:

 PS C:\temp> $stepsize = 30
 PS C:\temp> .\itunesForward.ps1

with iTunesForward.ps1 being

$iTunes = New-Object -ComObject iTunes.Application

if ($iTunes.playerstate -eq 1)
{
  $iTunes.PlayerPosition = $iTunes.PlayerPosition + $stepsize
}
1

In my particular use-case, I wanted to access the arguments from the profile which ignored the params, and simply checked for the existence of an argument (essentially a switch).

I have a batch script which runs a ps1 file but with a profile. That profile.ps1 outputs text when it loads. In some scripts, I want to disable the output of that text if I don't need it. For that, I created some simple switches such as the example below.

This is a very basic version, but you could extend it if you wished. Using the 'silent-running' mode an example then...

Inside my batch script:

C:\path\to\pwsh.exe -Command "%~dpn0.ps1" -QuietProfile

PowerShell script (inside profile.ps1):

[Boolean]$global:QuietProfile = [Boolean]([Environment]::GetCommandLineArgs() -match "-QuietProfile")

if (-not $global:QuietProfile) {
  Write-Host "I am some text which should not appear when -QuietProfile is passed"
}

By default (if you just opened pwsh.exe) then the $global:QuietProfile value will be false and you will see the output as normal.

Obviously you could pass -NoProfile in your command to prevent the profile being loaded at all, but there may be circumstances where you want some useful functions to load but not everything.

Not the answer you're looking for? Browse other questions tagged or ask your own question.