496

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?

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Boris Pavlović
  • 58,387
  • 26
  • 115
  • 142

7 Answers7

660

Tested as working:

#Must be the first statement in your script (not coutning 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'
)
Nux
  • 7,204
  • 5
  • 47
  • 62
Ocaso Protal
  • 17,084
  • 8
  • 69
  • 74
  • I think this way is more readable while executing the ps1 file. thanks – Campinho Oct 15 '15 at 21:18
  • 9
    what if the parameter is a string? What is the syntax? would it be something like -step '15' or -step "15" – Andrew Gray Nov 02 '15 at 00:04
  • 8
    @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. – Ocaso Protal Nov 02 '15 at 08:31
  • Thanks @OcasoProtal, yes I figured out single quotes were my friend. – Andrew Gray Nov 02 '15 at 09:11
  • 77
    FYI, to use multiple params, use this syntax: `param([string]$env,[string]$s3BucketName)` – Josh Padnick Dec 29 '15 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 Feb 22 '16 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. – Ocaso Protal Feb 23 '16 at 08:36
  • How can I pass an array of string with space? – Hrishikesh T T May 21 '18 at 14:08
  • I checked in windows 7: even `powershell.exe -file itunesForward.ps1 15` will work the same way. – Кое Кто Dec 19 '18 at 15:58
  • @JoshPadnick But what will the call look like? Will it just be the list of variable names with values like so: powershell.exe -file itunesForward.ps1 -step 15 step1 20 step2 25 step3 'whatever string'? And I will list them by their name at the start of the code? – Nimrod Yanai Apr 22 '19 at 12:35
  • 1
    Why would the `Int32` type be capitalized but `string` isn't? – starscream_disco_party Jun 05 '19 at 13:16
  • @starscream_disco_party Please see this: https://stackoverflow.com/questions/7074/what-is-the-difference-between-string-and-string-in-c – Ocaso Protal Jun 05 '19 at 13:18
  • @OcasoProtal thanks! Coming from Linux, damn near every design decision that MS makes makes absolutely no sense to me – starscream_disco_party Jun 05 '19 at 13:22
381

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
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
Emiliano Poggi
  • 22,882
  • 7
  • 49
  • 64
  • 59
    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 Jul 14 '12 at 06:21
  • 29
    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. – Florin Dumitrescu Nov 22 '13 at 15:57
  • 6
    named params in accepted solution also auto populate get-help – Pete Jul 21 '15 at 19:21
  • 3
    This answer is getting so much attention, please check out the related one which is much more complete. http://stackoverflow.com/questions/6359618/pass-parameter-from-batch-file-to-the-powershell-script/6362404#6362404 – Emiliano Poggi Sep 01 '16 at 13:55
22

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
Joma
  • 1,870
  • 20
  • 21
  • Does the `Position=0` setting turn it into a positional parameter rather than a flag? – FilBot3 Sep 05 '20 at 12:04
  • if you don't use the parameter names, you need to send correct values respecting the positions. Check the update for this answer. – Joma Sep 07 '20 at 03:12
8

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
}
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
ZEE
  • 2,131
  • 3
  • 25
  • 35
4

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.

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
JDennis
  • 624
  • 5
  • 15
3
# 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
}
Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
2

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
}
Froggy
  • 243
  • 1
  • 11