PowerShell ps1 फ़ाइल में कमांड-लाइन तर्क कैसे पास करें


90

सालों से, मैंने cmd/DOS/Windowsबैच फ़ाइलों के लिए शेल और कमांड लाइन तर्क का उपयोग किया है। उदाहरण के लिए, मैं एक फ़ाइल है, zuzu.batऔर उस में, मैं पहुँच %1, %2आदि अब, मैं जब मैं एक फोन भी ऐसा ही करना चाहते हैं PowerShellस्क्रिप्ट when I am in a Cmd.exe shell। मेरे पास एक स्क्रिप्ट है, xuxu.ps1(और मैंने पीएस 1 को अपने पथ चर और पॉवरशेल के साथ संबंधित पीएस 1 फाइलों को जोड़ दिया है)। लेकिन कोई फर्क नहीं पड़ता कि मैं क्या करूं, मुझे $argsचर से कुछ भी प्राप्त करने में असमर्थ लगता है । इसकी लंबाई हमेशा 0 होती है।

अगर मैं PowerShellइसके बजाय एक शेल में हूं cmd.exe, तो यह काम करता है (बेशक)। लेकिन मैं अभी तक पूरी तरह से सहज नहीं हूं ताकि पावरशेल के माहौल में रहूं। मैं टाइप नहीं करना चाहता 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

निर्दिष्ट स्क्रिप्ट को स्थानीय दायरे ("डॉट-सॉर्स्ड") में चलाता है, ताकि स्क्रिप्ट बनाने वाले फ़ंक्शन और चर वर्तमान सत्र में उपलब्ध हों। स्क्रिप्ट फ़ाइल पथ और किसी भी पैरामीटर दर्ज करें। फ़ाइल कमांड में अंतिम पैरामीटर होना चाहिए, क्योंकि फ़ाइल पैरामीटर नाम के बाद टाइप किए गए सभी अक्षर स्क्रिप्ट पैरामीटर के बाद स्क्रिप्ट फ़ाइल पथ के रूप में व्याख्या किए जाते हैं।

अर्थात

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

मतलब फ़ाइल को चलाते हैं myfile.ps1 और arg1 arg2 & arg3, PowerShell स्क्रिप्ट के लिए पैरामीटर हैं।


1
यह अभी भी मदद नहीं करता है कि ऑप क्या चाहता है ("मैं टाइप करना चाहता हूं xuxu p1 p2 p3 p4")।
थुडन

19

पॉवरशेल प्रलेखन के माध्यम से खुदाई करने के बाद, मैंने इस मुद्दे के बारे में कुछ उपयोगी जानकारी खोजी। $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

यह OP के लिए अपनी कमांड लाइन को powerhell.exe या pwsh के साथ शुरू करने का हिसाब नहीं देता है। ओपी के ऐसा करने पर व्यवहार बदल जाता है।
एरिक हेन्सन

1
@EricHansen मुझे नहीं पता कि आपका क्या मतलब है, मुझे एक ही परिणाम मिलता है या तो तरीका: `Powershell> powershell.exe। \ ParamTest.ps1 val1 val2 val3 val4 Num4 Args: 4 $ p1 = val2 $ P2 = val2 $ p3 = val3। $ p4 = val4 `
Randall Borck

@RandallBrock तर्कों का व्यवहार मेरे लिए बदल जाता है। अगर मैं CMD / बैच में हूं, और मैं ऐसा कुछ करता हूं pwsh .\ParamTest.ps1 -arg1 val1 -listOfArgs val2 val3 val4, तो यह वास्तव में ऐसा नहीं है। दूसरी ओर, अगर मैं पॉवरशेल में हूं और करता हूं .\ParamTest.ps1 -arg1 val1 -listOfArgs val2 val3 val4, तो वह काम करता है जैसे मुझे उम्मीद थी। मैंने सुना है कि यह "सुरक्षा कारणों" के कारण काम करने का इरादा है।
एरिक हैनसन

@EricHansen मुझे आश्चर्य है कि अगर यह एक संस्करण बात है। मेरे लिए, pwsh ने 6.2.0 लॉन्च किया, लेकिन शक्तियां। 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

1
@Timo मुझे नहीं पता कि आप वास्तव में क्या कर रहे हैं, लेकिन paramएक भाषा निर्माण है, हालांकि यह फ़ाइल में पहली चीज होनी चाहिए। क्या आपने इससे पहले एक चर या कुछ और घोषित किया था? यहाँ अधिक जानकारी: docs.microsoft.com/en-us/powershell/module/…
Randall Borck

18

ठीक है, इसलिए पहले यह PowerShell में एक बुनियादी सुरक्षा सुविधा को तोड़ रहा है। उस समझ के साथ, आप इसे कैसे कर सकते हैं:

  1. एक विंडोज एक्सप्लोरर विंडो खोलें
  2. मेनू उपकरण -> फ़ोल्डर विकल्प -> टैब फ़ाइल प्रकार
  3. PS1 फ़ाइल प्रकार ढूंढें और उन्नत बटन पर क्लिक करें
  4. न्यू बटन पर क्लिक करें
  5. कार्रवाई के लिए: खोलें
  6. आवेदन के लिए: "C: \ WINNT \ system32 \ WindowsPowerShell \ v1.0 \ powerhell.exe" "-file" "% 1"% *

आप -NoProfileअपनी प्रोफ़ाइल के आधार पर वहां भी एक तर्क रखना चाहते हैं ।


4
मुझे लगता है कि कुंजी आपके चरण 6 में है, जहां आप पैरामीटर में शक्तियां। डैनियल का कहना है कि उसके पास PS1 फाइलें पॉवरशेल के साथ जुड़ी हैं, लेकिन यह अतिरिक्त% 1% * चश्मे के बिना तर्क पारित नहीं करता है। यह भी ध्यान दें कि -File पैरामीटर V1 में उपलब्ध नहीं है। यह V2 के लिए नया है।
कीथ हिल

अच्छे पैरामीटर के बारे में अच्छा पकड़ मैं भूल गया था कि।
ईबीग्रीन

आपके सुझाव पर अमल करने से पहले मुझे V2 को इंस्टॉल करना होगा। धन्यवाद। जब आप कहते हैं कि यह एक बुनियादी सुरक्षा सुविधा को तोड़ रहा है, तो इसका अर्थ "यह" है? Cmd.exe से पॉवरशेल स्क्रिप्ट को कॉल करना जैसे कि यह एक .com / .bat / .exe फ़ाइल थी? स्क्रिप्ट के लिए पैरामीटर पास करना?
डैनियल 'डांग' ग्रिफ़िथ

1
क्षमा करें, मुझे और अधिक स्पष्ट होना चाहिए था। स्पष्ट रूप से शक्तियां कॉल करने के बिना स्क्रिप्ट को कॉल करना ।.exe। मैं यह नहीं कह रहा हूं कि यह आपके लिए व्यक्तिगत रूप से एक महत्वपूर्ण सुरक्षा विशेषता है और यह अस्पष्टता के माध्यम से सुरक्षा है जो मैं हमेशा वैसे भी प्रशंसक नहीं हूं।
ईबीग्रीन

6
EBGreen की टिप्पणी में जोड़ने के लिए, PowerShell की बचने की कोशिश करने वाली मूल सुरक्षा समस्या है लोग ईमेल से जुड़ी PS1 फ़ाइलों पर डबल-क्लिक करना और स्क्रिप्ट चलाना। इसीलिए PS1 फाइलें डिफ़ॉल्ट रूप से केवल एक संपादक से जुड़ी होती हैं। Microsoft वास्तव में ILoveYou वायरस का PowerShell संस्करण नहीं चाहता है, जैसे "LOVE-LETTER-FOR-YOU.TXT.ps1"
कीथ हिल

11

आप फ़ाइल में अपने मापदंडों को घोषित कर सकते हैं, जैसे कि परम:

[string]$para1
[string]$param2

और फिर PowerShell फ़ाइल को कॉल करें जैसे कि .\temp.ps1 para1 para2....para10, आदि।


6

हो सकता है कि आप PowerShell इनवोकेशन को किसी .batफ़ाइल में लपेट सकें

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

यदि आपने इस फ़ाइल को अपने फ़ोल्डर में किसी फ़ोल्डर में रखा है PATH, तो आप PowerShell स्क्रिप्ट को इस तरह से कॉल कर सकते हैं:

ps foo 1 2 3

उद्धृत करना थोड़ा गड़बड़ हो सकता है, हालांकि:

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

ट्रिपल उद्धरण दिखाने के लिए +1। वह मुझे थोड़ी देर के लिए अटक गया था।
डीनोके

1

जैसा कि लगता है आपको "xuxu p1 P2 p3 p4" नहीं मिल सकता है। लेकिन जब आप पॉवरशेल में होते हैं और आप सेट करते हैं

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" %*

यह मान रहा है कि शक्तियां। Exe आपके मार्ग में है

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


यह देखते हुए कि प्रशासक के रूप में cmd ​​प्रॉम्प्ट को चलाने की आवश्यकता है। इसके अलावा, मैं वास्तव में इसे विंडोज 10 संस्करण 1903 (18362.778) पर काम करने के लिए संघर्ष कर रहा हूं - सभी कमांड सफलतापूर्वक चलते हैं लेकिन तर्क अभी भी पास नहीं होते हैं। मुझे लगता है कि .bat फ़ाइल के साथ लपेटना सबसे पोर्टेबल समाधान है।
डेविड ऐरापिल्टन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.