배치 파일을 사용하여 PowerShell 스크립트를 더 쉽게 실행하는 방법
여러 가지 이유로 인해 보안 관련 PowerShell 스크립트는 배치 스크립트와 같이 쉽게 이식 가능하고 유용하지 않습니다. 그러나 이러한 문제를 해결하기 위해 PowerShell 스크립트와 함께 배치 스크립트를 번들로 제공 할 수 있습니다. 여기에서는 이러한 문제 영역 중 일부를 보여주고 배치 스크립트를 작성하여 문제를 해결하는 방법에 대해 설명합니다.
왜 .PS1 파일을 다른 컴퓨터에 복사하여 실행할 수 없습니까??
임의의 스크립트를 실행하고, 필요한 권한으로 적절한 설정을 사용하도록 대상 시스템을 미리 구성하지 않은 경우, 이렇게하려고 할 때 몇 가지 문제가 발생할 가능성이 있습니다.
- PowerShell은 기본적으로 .PS1 파일 확장명과 연결되지 않습니다..
처음에는 PowerShell Geek School 시리즈에서이 기능을 사용했습니다. Windows는 .PS1 파일을 PowerShell 명령 인터프리터로 보내는 대신 기본적으로 메모장에 연결합니다. 이는 단순히 악의적 인 스크립트를 두 번 클릭하여 우발적 인 실행을 방지하기위한 것입니다. 이 동작을 변경할 수있는 방법이 있지만 스크립트를 가지고 다니는 모든 컴퓨터에서 수행하려는 작업은 아닙니다. 특히 자신의 컴퓨터가 아닌 경우. - PowerShell은 기본적으로 외부 스크립트 실행을 허용하지 않습니다..
PowerShell의 ExecutionPolicy 설정은 모든 버전의 Windows에서 기본적으로 외부 스크립트의 실행을 차단합니다. 일부 Windows 버전에서 기본값은 스크립트 실행을 전혀 허용하지 않습니다. Windows 7에서 PowerShell 스크립트 실행을 허용하는 방법에서이 설정을 변경하는 방법을 보여 줬습니다. 그러나 이것은 어떤 컴퓨터에서도 원하지 않는 것입니다. - 일부 PowerShell 스크립트는 관리자 권한없이 작동하지 않습니다..
관리자 수준의 계정으로 실행하는 경우에도 특정 작업을 수행하려면 UAC (사용자 계정 컨트롤)를 통과해야합니다. 이 기능을 사용 중지하지 않으려 고하지만 나중에 처리하기가 더 쉬울 때도 좋습니다.. - 일부 사용자는 PowerShell 환경을 사용자 지정할 수 있습니다..
아마도이 문제에 자주 빠지지는 않겠지 만 그렇게하면 스크립트를 실행하고 문제를 해결할 수 있습니다. 다행히도 우리는 영구적 인 변화없이이 문제를 해결할 수 있습니다..
1 단계 : 두 번 클릭하여 실행.
먼저 .PS1 파일 연결 문제를 해결해 보겠습니다. .PS1 파일을 실행하려면 두 번 클릭 할 수 없지만 그런 식으로 .BAT 파일을 실행할 수는 있습니다. 따라서 우리는 명령 줄에서 PowerShell 스크립트를 호출하는 배치 파일을 작성합니다..
따라서 모든 스크립트에 대해 배치 파일을 다시 작성할 필요가 없으며 스크립트를 이동할 때마다 자체 참조 변수를 사용하여 PowerShell 스크립트의 파일 경로를 작성하게됩니다. 이 작업을 수행하려면 배치 파일을 PowerShell 스크립트와 동일한 폴더에 저장하고 파일 이름이 같아야합니다. 따라서 PowerShell 스크립트의 이름이 "MyScript.ps1"이라면 배치 파일의 이름을 "MyScript.bat"로 지정하고 동일한 폴더에 있는지 확인해야합니다. 그런 다음 배치 스크립트에 다음 줄을 넣으십시오.
@ECHO OFF PowerShell.exe -Command "& '% ~ dpn0.ps1'"PAUSE
다른 보안 제한 사항이 없다면 배치 파일에서 PowerShell 스크립트를 실행하는 것이 전부입니다. 사실, 첫 번째와 마지막 줄은 주로 선호의 문제입니다. 두 번째 줄은 실제로 작업을 수행하는 것입니다. 여기에 고장이 있습니다 :
@ECHO OFF 명령 에코를 끕니다. 이렇게하면 배치 파일이 실행될 때 다른 명령이 화면에 표시되지 않습니다. 이 선은 그 앞에 at 기호 (@)를 사용하여 숨겨져 있습니다..
PowerShell.exe -Command "& '% ~ dpn0.ps1'" 실제로 PowerShell 스크립트를 실행합니다. 물론 PowerShell.exe는 모든 CMD 창이나 배치 파일에서 호출하여 PowerShell을 평소와 같이 맨손으로 실행할 수 있습니다. -Command 매개 변수와 적절한 인수를 포함하여 배치 파일에서 직접 명령을 실행하는 데 사용할 수도 있습니다. .PS1 파일을 대상으로 사용하는 방법은 특수 % ~ dpn0 변수를 사용하는 것입니다. 배치 파일에서 실행하면 % ~ dpn0은 배치 파일의 드라이브 문자, 폴더 경로 및 파일 이름 (확장자 없음)을 평가합니다. 배치 파일과 PowerShell 스크립트는 동일한 폴더에 있고 이름이 같기 때문에 % ~ dpn0.ps1은 PowerShell 스크립트의 전체 파일 경로로 변환됩니다.
중지 배치 실행을 일시 중지하고 사용자 입력을 기다립니다. 이것은 일반적으로 배치 파일의 끝에 있기 때문에 창이 사라지기 전에 명령 출력을 검토 할 수 있습니다. 각 단계의 테스트를 거치면서이 유용성이 더욱 분명해질 것입니다.
따라서 기본 배치 파일이 설정됩니다. 데모 목적으로이 파일은 "D : \ Script Lab \ MyScript.bat"로 저장되며 같은 폴더에 "MyScript.ps1"이 있습니다. MyScript.bat를 두 번 클릭하면 어떻게되는지 봅시다..
당연히 PowerShell 스크립트는 실행되지 않았지만 예상대로입니다. 결국 네 가지 문제 중 첫 번째 문제 만 해결했습니다. 그러나 여기에 설명 된 몇 가지 중요한 비트가 있습니다.
- 창 제목은 배치 스크립트가 PowerShell을 성공적으로 시작했음을 나타냅니다..
- 첫 번째 출력 줄에서는 사용자 지정 PowerShell 프로필이 사용 중임을 보여줍니다. 위에 열거 된 잠재적 문제 # 4.
- 오류 메시지는 실제로 ExecutionPolicy 제한 사항을 보여줍니다. 그것이 우리의 문제 # 2입니다..
- 오류 메시지의 밑줄 친 부분 (기본적으로 PowerShell의 오류 출력으로 수행됨)은 배치 스크립트가 의도 한 PowerShell 스크립트 (D : \ Script Lab \ MyScript.ps1)를 올바르게 대상으로 지정했음을 보여줍니다. 그래서 우리는 적어도 많은 것이 제대로 작동하고 있다는 것을 알고 있습니다..
이 경우 프로필은이 데모에서 프로필이 활성화 될 때마다 출력을 생성하는 데 사용되는 간단한 한 줄짜리 스크립트입니다. 이러한 스크립트를 직접 테스트하려는 경우 자신의 PowerShell 프로필을 사용자 지정할 수도 있습니다. 프로필 스크립트에 다음 줄을 추가하기 만하면됩니다.
쓰기 출력 '사용자 지정 PowerShell 프로필이 적용되었습니다!'
여기서 테스트 시스템의 ExecutionPolicy는 RemoteSigned로 설정됩니다. 이렇게하면 신뢰할 수있는 기관에서 서명하지 않은 경우 프로필 스크립트와 같이 로컬로 만든 스크립트를 실행하고 외부 원본의 스크립트를 차단할 수 있습니다. 데모 목적으로 다음 명령을 사용하여 MyScript.ps1을 외부 소스의 것으로 플래그 지정합니다.
Add-Content -Path 'D : \ Script Lab \ MyScript.ps1'- 값 "[ZoneTransfer] 'nZoneId = 3"-Stream'Zone.Identifier '
그러면 MyScript.ps1에 Zone.Identifier 대체 데이터 스트림이 설정되어 Windows에서 파일이 인터넷에서 온 것임을 알립니다. 다음 명령을 사용하여 쉽게 되돌릴 수 있습니다.
Clear-Content -Path 'D : \ Script Lab \ MyScript.ps1'-Stream 'Zone.Identifier'
2 단계 : ExecutionPolicy 둘러보기.
ExecutionPolicy 설정을 CMD 또는 배치 스크립트에서 가져 오는 것은 실제로 매우 쉽습니다. PowerShell.exe 명령에 하나 이상의 매개 변수를 추가하기 위해 스크립트의 두 번째 줄을 수정하기 만하면됩니다..
PowerShell.exe -ExecutionPolicy Bypass -Command "& '% ~ dpn0.ps1'"
-ExecutionPolicy 매개 변수는 새 PowerShell 세션을 생성 할 때 사용되는 ExecutionPolicy를 수정하는 데 사용할 수 있습니다. 이 세션 이상으로 지속되지 않으므로 시스템의 일반적인 보안 상태를 약화시키지 않으면 서 필요할 때마다 PowerShell을 실행할 수 있습니다. 이제이를 수정 했으므로 다른 것을 시도해 봅시다.
스크립트가 제대로 실행되었으므로 실제로 무엇을하는지 볼 수 있습니다. 제한된 사용자로 스크립트를 실행하고 있음을 알려줍니다. 이 스크립트는 실제로 관리자 권한이있는 계정으로 실행되지만 사용자 계정 컨트롤이 진행되고 있습니다. 스크립트가 관리자 액세스를 확인하는 방법에 대한 자세한 내용은이 기사에서 다루지 않지만 데모에 사용되는 코드는 다음과 같습니다.
IsInRole ([Security.Principal.WindowsBuiltInRole] "관리자")) Write-Output '관리자 권한으로 실행 중입니다.' else (Security.Principal.WindowsIdentity :: GetCurrent () Write-Output 'Running Limited!' 일시 중지
또한 스크립트 출력에는 두 개의 "일시 중지"작업이 있음을 알 수 있습니다. 하나는 PowerShell 스크립트이고 다른 하나는 배치 파일입니다. 그 이유는 다음 단계에서 더 분명해질 것입니다..
3 단계 : 관리자 액세스 권한 얻기.
스크립트가 권한 상승이 필요한 명령을 실행하지 않고 누군가의 사용자 정의 프로파일에 대해 걱정할 필요가 없다고 확신 할 경우 나머지 부분은 건너 뛸 수 있습니다. 관리자 수준 cmdlet을 일부 실행하는 경우이 조각이 필요합니다..
불행히도 배치 파일 또는 CMD 세션 내에서 고도에 대해 UAC를 트리거 할 수있는 방법은 없습니다. 그러나 PowerShell을 사용하면 Start-Process에서이 작업을 수행 할 수 있습니다. 인수에 "-Verb RunAs"를 사용하면 Start-Process는 관리자 권한으로 응용 프로그램을 시작하려고 시도합니다. PowerShell 세션이 아직 상승되지 않은 경우 UAC 프롬프트가 트리거됩니다. 이 스크립트를 실행하기 위해 배치 파일에서이 스크립트를 사용하려면 Start-Process를 실행하는 두 개의 PowerShell 프로세스와 Start-Process에서 시작한 다른 두 개의 PowerShell 프로세스를 생성하여 스크립트를 실행해야합니다. 배치 파일의 두 번째 줄을 다음과 같이 변경해야합니다.
PowerShell.exe - 명령 "& 시작 프로세스 PowerShell.exe -ArgumentList '-ExecutionPolicy 우회 - 파일" "% ~ dpn0.ps1" "'-Verb RunAs"
배치 파일을 실행하면 PowerShell 프로필 스크립트의 첫 번째 출력 줄이 표시됩니다. Start-Process가 MyScript.ps1을 시작하려고하면 UAC 프롬프트가 나타납니다..
UAC 프롬프트를 클릭하면 새 PowerShell 인스턴스가 생성됩니다. 물론 이것은 새로운 인스턴스이기 때문에 프로필 스크립트 고지를 다시 볼 것입니다. 그런 다음 MyScript.ps1이 실행되고 실제로 상승 된 세션에 있음을 알 수 있습니다..
여기에도 두 가지 일시 중지 이유가 있습니다. PowerShell 스크립트의 스크립트가 아니라면 스크립트의 출력을 볼 수 없습니다. 스크립트 실행이 끝나면 PowerShell 창이 팝업되고 사라집니다. 그리고 배치 파일의 일시 중지없이 PowerShell을 처음 시작하는 데 오류가 있는지 확인할 수 없습니다..
4 단계 : 사용자 지정 PowerShell 프로필 둘러보기.
그 끔찍한 사용자 정의 프로필 통지를 제거하자. 여기에서는 거의 성가신 일이 없지만 사용자의 PowerShell 프로필이 기본 설정, 변수 또는 기능을 스크립트로 예상하지 못한 방식으로 변경하면 실제로 문제가 될 수 있습니다. 프로필없이 스크립트를 실행하는 것이 훨씬 간단하므로 걱정할 필요가 없습니다. 그렇게하기 위해 배치 파일의 두 번째 줄을 한 번 더 변경하면됩니다.
PowerShell.exe -NoProfile -Command "& Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File" "% ~ dpn0.ps1" "'-Verb RunAs"명령을 실행하십시오.
스크립트에 의해 시작되는 PowerShell 인스턴스에 -NoProfile 매개 변수를 추가하면 사용자 프로필 스크립트가 두 단계에서 완전히 무시되고 PowerShell 스크립트가 상당히 예측 가능한 기본 환경에서 실행됩니다. 여기서, 생성 된 쉘 중 하나에 사용자 정의 프로파일 통지가 없음을 볼 수 있습니다.
PowerShell 스크립트에서 관리자 권한이 필요하지 않고 3 단계를 건너 뛴 경우 두 번째 PowerShell 인스턴스없이 수행 할 수 있으며 배치 파일의 두 번째 줄은 다음과 같아야합니다.
PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command "& '% ~ dpn0.ps1'"
결과는 다음과 같습니다.
(물론 관리자가 아닌 스크립트의 경우, 모든 콘솔이 동일한 콘솔 창에 캡처되고 끝날 때까지 일시 중지 되어도 PowerShell 스크립트에서 스크립트 끝내기없이이 작업을 수행 할 수 있습니다. 어쨌든 배치 파일.)
배치 파일을 완료했습니다..
PowerShell 스크립트에 대한 관리자 권한이 필요한지 여부에 따라 (그리고 실제로 권한을 요청하지 않아야 함) 최종 배치 파일은 아래 두 가지 중 하나처럼 보입니다..
관리자 권한이없는 경우 :
@ECHO OFF PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command "& '% ~ dpn0.ps1'"PAUSE
관리 액세스 권한 :
@ECHO OFF PowerShell.exe -NoProfile -Command "& Start-Process PowerShell.exe -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File" "% ~ dpn0.ps1" "'-Verb RunAs"PAUSE
배치 파일을 사용하려는 PowerShell 스크립트와 동일한 폴더에 배치하고 동일한 이름을 지정해야합니다. 그런 다음 어떤 파일 시스템을 사용하더라도 시스템의 모든 보안 설정을 사용하지 않고도 PowerShell 스크립트를 실행할 수 있습니다. 매번 수동으로 변경 사항을 수동으로 수행 할 수 있지만 문제가 발생하지 않으며 나중에 변경 내용을 되돌릴 필요가 없습니다..
참고 문헌 :
- 배치 파일에서 PowerShell 스크립트 실행 - Daniel Schroeder의 프로그래밍 블로그
- PowerShell에서 관리자 권한 확인 - 안녕하세요, Scripting Guy! 블로그