PowerShell PS1 파일에 명령 줄 인수를 전달하는 방법


90

수년 동안 나는 cmd/DOS/Windows셸 을 사용하고 명령 줄 인수를 배치 파일에 전달했습니다. 예를 들어, 내가 파일을 가지고 zuzu.bat있으며, 나는 액세스 %1, %2등 지금, 나는 내가 호출 할 때 동일한 작업을 수행 할 PowerShell스크립트를 when I am in a Cmd.exe shell. 스크립트가 있습니다 xuxu.ps1(그리고 PS1을 PATHEXT 변수에 추가하고 PS1 파일을 PowerShell과 연결했습니다). 그러나 내가 무엇을하든 $args변수 에서 아무것도 얻을 수없는 것 같습니다 . 항상 길이가 0입니다.

나는에서 오전하면 PowerShell쉘, 대신 cmd.exe, 그것은 (물론) 작동합니다. 그러나 저는 아직 PowerShell 환경에서 풀 타임으로 살기에 충분히 편하지 않습니다. 를 입력하고 싶지 않습니다 powershell.exe -command xuxu.ps1 p1 p2 p3 p4. 를 입력하고 싶습니다 xuxu p1 p2 p3 p4.

이것이 가능합니까? 그렇다면 어떻게합니까?

작업 할 수없는 샘플은 foo.ps1입니다.

Write-Host "Num Args:" $args.Length;
foreach ($arg in $args) {
    Write-Host "Arg: $arg";
}

결과는 항상 다음과 같습니다.

C:\temp> foo
Num Args: 0
C:\temp> foo a b c d
Num Args: 0
c:\temp>

답변:


34

이 기사가 도움 됩니다. 특히이 섹션은 다음과 같습니다.

-파일

로컬 범위 ( "점 소스")에서 지정된 스크립트를 실행하여 스크립트가 만드는 함수와 변수를 현재 세션에서 사용할 수 있도록합니다. 스크립트 파일 경로와 매개 변수를 입력합니다. File 매개 변수 이름 뒤에 입력 된 모든 문자는 스크립트 매개 변수가 뒤 따르는 스크립트 파일 경로로 해석되기 때문에 File은 명령의 마지막 매개 변수 여야합니다.

powershell.exe -File "C:\myfile.ps1" arg1 arg2 arg3

myfile.ps1 파일을 실행하고 arg1 arg2 및 arg3은 PowerShell 스크립트의 매개 변수입니다.


1
이것은 여전히 ​​op가 원하는 것에 도움이되지 않습니다 ( "I want to type xuxu p1 p2 p3 p4").
thdoan

19

PowerShell 설명서를 살펴본 후이 문제에 대한 유용한 정보를 발견했습니다. 파일 시작 부분에 $args를 사용한 경우를 사용할 수 없습니다 param(...). 대신 $PSBoundParameters. 코드를 PowerShell 스크립트에 복사 / 붙여 넣기했는데 PowerShell 버전 2에서 예상 한대로 작동했습니다 (이 문제가 발생했을 때 사용중인 버전이 확실하지 않습니다).

사용중인 경우 $PSBoundParameters( param(...)스크립트 시작 부분에서 사용하는 경우에만 작동 함 ), 배열이 아니고 해시 테이블이므로 키 / 값 쌍을 사용하여 참조해야합니다.

param($p1, $p2, $p3, $p4)
$Script:args=""
write-host "Num Args: " $PSBoundParameters.Keys.Count
foreach ($key in $PSBoundParameters.keys) {
    $Script:args+= "`$$key=" + $PSBoundParameters["$key"] + "  "
}
write-host $Script:args

그리고 전화를 걸면 ...

PS> ./foo.ps1 a b c d

결과는 ...

Num Args:  4
$p1=a  $p2=b  $p3=c  $p4=d

이것은 powershell.exe 또는 pwsh로 명령 줄을 시작하는 OP를 고려하지 않습니다. OP가 그렇게 할 때 동작이 변경됩니다.
Eric Hansen 19

1
@EricHansen 무슨 뜻인지 모르겠습니다. 어느 쪽이든 동일한 결과를 얻습니다.`Powershell> powershell.exe. \ ParamTest.ps1 val1 val2 val3 val4 Num Args : 4 $ p1 = val1 $ p2 = val2 $ p3 = val3 $ P4 = val4`
랜달 Borck

@RandallBrock 인수의 행동이 저에게 바뀝니다. 내가 CMD / 배치에 있고 pwsh .\ParamTest.ps1 -arg1 val1 -listOfArgs val2 val3 val4, 같은 일을한다면, 정말 그게 싫습니다. 반면에 PowerShell을 사용하고을 수행 .\ParamTest.ps1 -arg1 val1 -listOfArgs val2 val3 val4하면 예상대로 작동합니다. 이것이 "보안상의 이유"로 인해 작동하는 방식이라고 들었습니다.
Eric Hansen

@EricHansen 버전 문제인지 궁금합니다. 저에게 pwsh는 6.2.0을 시작하지만 powershell.exe는 5.1.17134.858을 시작합니다. 둘 다 나열된 동일한 결과를 생성합니다. 결과 Powershell>pwsh .\ParamTest.ps1 val1 val2 val3 val4:Num Args: 4 $p1=val1 $p2=val2 $p3=val3 $p4=val4
Randall Borck 19

1
@Timo 정확히 무엇을하는지 모르겠지만 param언어 구조이지만 파일에서 가장 먼저해야합니다. 그 전에 변수 나 다른 것을 선언 했습니까? 추가 정보 : docs.microsoft.com/en-us/powershell/module/…
Randall Borck

18

좋습니다. 먼저 이것은 PowerShell의 기본 보안 기능을 깨는 것입니다. 이를 이해하면 다음과 같이 할 수 있습니다.

  1. Windows 탐색기 열기 창을
  2. 메뉴 도구 -> 폴더 옵션 -> 탭 파일 유형
  3. PS1 파일 유형을 찾아 고급 버튼을 클릭하십시오
  4. 새로 만들기 버튼을 클릭하십시오.
  5. 액션 넣어 : 열기
  6. 응용 프로그램의 경우 : "C : \ WINNT \ system32 \ WindowsPowerShell \ v1.0 \ powershell.exe" "-file" "% 1"% *

-NoProfile프로필이 무엇을하는지에 따라 거기에 논쟁도 할 수 있습니다 .


4
키는 powershell.exe에 매개 변수를 전달하는 6 단계에 있다고 생각합니다. Daniel은 PS1 파일을 PowerShell과 연결했지만 추가 % 1 % * 사양 없이는 인수를 전달하지 않는다고 말합니다. 또한 -File 매개 변수는 V1에서 사용할 수 없습니다. V2의 새로운 기능입니다.
Keith Hill

내가 잊어 버린 -file 매개 변수에 대한 좋은 캐치.
EBGreen

제안을 시도하기 전에 V2를 설치해야합니다. 감사. 이것이 기본 보안 기능을 깨고 있다고 말할 때 "이"란 무엇을 의미합니까? .com / .bat / .exe 파일 인 것처럼 Cmd.exe에서 PowerShell 스크립트를 호출합니까? 매개 변수를 스크립트에 전달 하시겠습니까?
Daniel 'Dang'Griffith

1
더 명확 했어야해서 죄송합니다. powershell.exe를 명시 적으로 호출하지 않고 스크립트를 호출합니다. 개인적으로 중요한 보안 기능이라고 말하는 것은 아니며, 어차피 항상 팬이 아닌 모호함을 통한 보안입니다.
EBGreen

6
EBGreen의 의견에 추가하기 위해 PowerShell이 ​​피하려는 기본 보안 문제는 이메일에 첨부 된 PS1 파일을 두 번 클릭하고 스크립트를 실행하는 것입니다. 그렇기 때문에 PS1 파일은 기본적으로 편집기에만 연결됩니다. Microsoft는 ILoveYou 바이러스의 PowerShell 버전 (예 : "LOVE-LETTER-FOR-YOU.TXT.ps1")을 원하지 않습니다
Keith Hill

12

param과 같이 파일에서 매개 변수를 선언 할 수 있습니다.

[string]$para1
[string]$param2

그런 다음 PowerShell 파일을 이렇게 호출하십시오 .\temp.ps1 para1 para2....para10.


6

다음 .bat과 같이 파일에 PowerShell 호출을 래핑 할 수 있습니다 .

rem ps.bat
@echo off
powershell.exe -command "%*"

그런 다음이 파일을의 폴더 아래에 배치하면 다음 PATH과 같이 PowerShell 스크립트를 호출 할 수 있습니다.

ps foo 1 2 3

그러나 견적은 약간 지저분해질 수 있습니다.

ps write-host """hello from cmd!""" -foregroundcolor green

삼중 따옴표를 표시하려면 +1합니다. 그것은 나를 한동안 붙어있게했다.
DeanOC

1

보이는대로 "xuxu p1 p2 p3 p4"를 얻지 못할 수도 있습니다. 하지만 PowerShell에서 설정하면

PS > set-executionpolicy Unrestricted -scope currentuser

다음과 같은 스크립트를 실행할 수 있습니다.

./xuxu p1 p2 p3 p4

또는

.\xuxu p1 p2 p3 p4

또는

./xuxu.ps1 p1 p2 p3 p4

PowerShell을 좀 더 편안하게 사용할 수 있기를 바랍니다.


0

cmd에서 ps1 스크립트를 호출하고 스크립트를 호출하지 않고 인수를 전달하려면

powershell.exe script.ps1 -c test
script -c test ( wont work )

당신은 다음을 할 수 있습니다

setx PATHEXT "%PATHEXT%;.PS1;" /m
assoc .ps1=Microsoft.PowerShellScript.1
ftype Microsoft.PowerShellScript.1=powershell.exe "%1" %*

이것은 powershell.exe가 경로에 있다고 가정합니다.

https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/ftype


관리자 권한으로 cmd 프롬프트를 실행해야합니다. 또한 실제로 Windows 10 버전 1903 (18362.778)에서 작동하도록 고군분투하고 있습니다. 모든 명령이 성공적으로 실행되지만 인수는 여전히 전달되지 않습니다. .bat 파일로 래핑하는 것이 가장 이식 가능한 솔루션이라고 생각합니다.
David Airapetyan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.