다음 시나리오를 통해 내 필요를 표현할 수 있습니다 . 기본 명령으로 실행할 문자열을 허용하는 함수를 작성하십시오.
아이디어를 너무 많이 얻지 못했습니다. 회사의 다른 곳에서 다른 명령 줄 유틸리티와 인터페이스하여 명령을 제공하는 명령을 제공하는 경우. 명령을 제어하지 않으므로 유효한 명령을 input 으로 승인해야합니다 . 이것들은 내가 쉽게 극복 할 수 없었던 주요 딸꾹질입니다.
-
명령은 공백이있는 경로에있는 프로그램을 실행할 수 있습니다.
$command = '"C:\Program Files\TheProg\Runit.exe" Hello';
-
이 명령에는 공백이있는 매개 변수가있을 수 있습니다.
$command = 'echo "hello world!"';
-
이 명령에는 단일 눈금과 이중 눈금이 모두있을 수 있습니다.
$command = "echo `"it`'s`"";
거기에 모든 이를 달성 깨끗한 방법은? 나는 화려하고 추악한 해결책을 고안 할 수 있었지만 스크립팅 언어의 경우 이것이 간단하게 죽어야한다고 생각합니다.
답변
Invoke-Expression
로 별칭이 지정됩니다 iex
. 다음은 예제 # 2 및 # 3에서 작동합니다.
iex $command
exe가 따옴표 안에 있기 때문에 예제 # 1과 같은 일부 문자열은 그대로 실행되지 않습니다. 문자열의 내용이 Powershell 명령 프롬프트에서 바로 실행하는 방식이기 때문에 그대로 작동합니다.
$command = 'C:\somepath\someexe.exe somearg'
iex $command
그러나 exe가 따옴표로 묶인 &
경우이 예제에서와 같이 명령 행에서 실행할 때 실행되도록 하는 데 도움이 필요합니다 .
>> &"C:\Program Files\Some Product\SomeExe.exe" "C:\some other path\file.ext"
그리고 스크립트에서 :
$command = '"C:\Program Files\Some Product\SomeExe.exe" "C:\some other path\file.ext"'
iex "& $command"
"
이 순진한 구현 에서처럼 명령 문자열의 첫 문자가 인 경우를 감지하여 거의 모든 경우를 처리 할 수 있습니다 .
function myeval($command) {
if ($command[0] -eq '"') { iex "& $command" }
else { iex $command }
}
그러나 다른 방식으로 호출해야하는 다른 경우가있을 수 있습니다. 이 경우 try{}catch{}
특정 예외 유형 / 메시지에 대해을 사용하거나 명령 문자열을 검사해야합니다.
상대 경로 대신 항상 절대 경로를 수신하는 경우 위의 2 이외의 특별한 경우가 많지 않아야합니다.
답변
기본적으로 PowerShell을 사용하여 쉘 명령을 실행하는 것이 얼마나 어려운지에 대한이 Microsoft Connect 보고서를 참조하십시오 (아, 아이러니).
http://connect.microsoft.com/PowerShell/feedback/details/376207/
그들은 --%
PowerShell이 텍스트를 오른쪽으로 해석하는 것을 멈추게하는 방법으로 사용 하는 것이 좋습니다 .
예를 들면 다음과 같습니다.
MSBuild /t:Publish --% /p:TargetDatabaseName="MyDatabase";TargetConnectionString="Data Source=.\;Integrated Security=True" /p:SqlPublishProfilePath="Deploy.publish.xml" Database.sqlproj
답변
제거 문자열에 대한 레지스트리를 구문 분석하고 실행할 때 허용 된 답변이 작동하지 않았습니다. 결국 전화가 필요하지 않은 것으로 나타났습니다 Invoke-Expression
.
마지막으로 제거 문자열을 실행하는 방법을 알기 위해이 멋진 템플릿 을 발견했습니다 .
$path = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall'
$app = 'MyApp'
$apps= @{}
Get-ChildItem $path |
Where-Object -FilterScript {$_.getvalue('DisplayName') -like $app} |
ForEach-Object -process {$apps.Set_Item(
$_.getvalue('UninstallString'),
$_.getvalue('DisplayName'))
}
foreach ($uninstall_string in $apps.GetEnumerator()) {
$uninstall_app, $uninstall_arg = $uninstall_string.name.split(' ')
& $uninstall_app $uninstall_arg
}
이것은 나를 위해 작동합니다. 즉, $app
내가 알고있는 사내 응용 프로그램이 두 가지 주장 만 가질 것입니다. 보다 복잡한 설치 제거 문자열의 경우 결합 연산자 를 사용할 수 있습니다 . 또한 방금 해시 맵을 사용했지만 실제로 배열을 사용하고 싶을 것입니다.
또한 동일한 응용 프로그램의 여러 버전이 설치되어 있으면이 제거 프로그램이 한 번에 모두 순환하여 혼란 스럽 MsiExec.exe
습니다.
답변
호출 연산자를 사용하려는 경우 인수는 변수에 저장된 배열 일 수 있습니다.
$prog = 'c:\windows\system32\cmd.exe'
$myargs = '/c','dir','/x'
& $prog $myargs
호출 연산자는 ApplicationInfo 객체와도 작동합니다.
$prog = get-command cmd
$myargs = -split '/c dir /x'
& $prog $myargs