पॉवरशेल ISE ​​के अंदर किसी अन्य PS1 स्क्रिप्ट से PowerShell स्क्रिप्ट PS1 को कॉल करें


138

मैं Powershell ISE के अंदर एक दूसरी myScript2.ps1 स्क्रिप्ट के अंदर एक myScript1.ps1 स्क्रिप्ट के लिए कॉल निष्पादन चाहता हूं।

MyScript2.ps1 के अंदर निम्न कोड, Powershell प्रशासन से ठीक काम करता है, लेकिन PowerShell ISE के अंदर काम नहीं करता है:

#Call myScript1 from myScript2
invoke-expression -Command .\myScript1.ps1

जब मैं PowerShell ISE से MyScript2.ps1 निष्पादित करता हूं तो मुझे निम्न त्रुटि मिलती है:

शब्द '। \ _ MyScript1.ps1' को एक cmdlet, फ़ंक्शन, स्क्रिप्ट फ़ाइल या उपयुक्त प्रोग्राम के नाम के रूप में मान्यता प्राप्त नहीं है। नाम की वर्तनी की जाँच करें, या यदि कोई पथ शामिल किया गया था, तो सत्यापित करें कि पथ सही है और पुन: प्रयास करें।

जवाबों:


83

स्क्रिप्ट का स्थान खोजने के लिए, उपयोग करें Split-Path $MyInvocation.MyCommand.Path(सुनिश्चित करें कि आप इसका उपयोग स्क्रिप्ट संदर्भ में करते हैं)।

कारण है कि आप का उपयोग करना चाहिए और कुछ नहीं इस उदाहरण स्क्रिप्ट के साथ सचित्र किया जा सकता है।

## ScriptTest.ps1
Write-Host "InvocationName:" $MyInvocation.InvocationName
Write-Host "Path:" $MyInvocation.MyCommand.Path

यहाँ कुछ परिणाम हैं।

PS C: \ Users \ JasonAr>। ScriptTest.ps1
मंगलाचरण:। \ ScriptTest.ps1
पथ: C: \ Users \ JasonAr \ ScriptTest.ps1

PS C: \ Users \ JasonAr>। । \ ScriptTest.ps1
मंगलाचरण:।
पथ: C: \ Users \ JasonAr \ ScriptTest.ps1

PS C: \ Users \ JasonAr> & "। ​​\ ScriptTest.ps1"
मंगलाचरण: और
पथ: C: \ Users \ JasonAr \ ScriptTest.ps1

में PowerShell 3.0 और बाद में आप स्वत: चर का उपयोग कर सकते हैं $PSScriptRoot:

## ScriptTest.ps1
Write-Host "Script:" $PSCommandPath
Write-Host "Path:" $PSScriptRoot
PS C: \ Users \ jarcher>। \ ScriptTest.ps1
स्क्रिप्ट: C: \ Users \ jarcher \ ScriptTest.ps1
पथ: C: \ Users \ jarcher

एक देर के अलावा: यदि आप अबॉट वेरिएंट से चिंतित हैं (या, वास्तव में, बस "ठोस" कोड चाहते हैं) तो आप शायद "राइट-होस्ट" के बजाय "राइट-आउटपुट" का उपयोग करना चाहते हैं।
KlaymenDK

20
उत्तर में स्प्लिट-पाथ का एक उदाहरण उपयोग देखना अच्छा होगा। आपको वास्तव में किसी अन्य स्क्रिप्ट के अंदर एक स्क्रिप्ट को दिखाने की भी आवश्यकता है।
जेरेमी

37

MyScript1.ps1 का वर्तमान पथ myScript2.ps1 के समान नहीं है। आप MyScript2.ps1 के फ़ोल्डर पथ को प्राप्त कर सकते हैं और इसे MyScript1.ps1 पर संक्षिप्त कर सकते हैं और फिर निष्पादित कर सकते हैं। दोनों स्क्रिप्ट एक ही स्थान पर होनी चाहिए।

## MyScript2.ps1 ##
$ScriptPath = Split-Path $MyInvocation.InvocationName
& "$ScriptPath\MyScript1.ps1"

मुझे $ MyInvocation वैरिएबल को इनिशियलाइज़ कैसे करना है?
निकोला सेलिएंटो

आप नहीं, यह एक स्वचालित चर है।
शाए लेवी

यह काम करता है, लेकिन कहा जाता है स्क्रिप्ट के वास्तव में निष्पादन से पहले निम्नलिखित त्रुटि प्राप्त करें: स्प्लिट-पाथ: पैरामीटर 'Path' के लिए तर्क को बाध्य नहीं कर सकता क्योंकि यह एक खाली स्ट्रिंग है। 4 चार: लाइन पर 25 + $ ScriptPath = स्प्लिट-पथ <<<< $ MyInvocation.InvocationName + CategoryInfo: InvalidData: (:) [स्प्लिट-पथ], ParameterBindingValidationException + FullyQualifiedErrorId: ParameterArgumentValidationErrorEmptyStringNotAllowed, Microsoft.PowerShell.Commands.SplitPathCommand
निकोला सेलिएंटो

एक नई स्क्रिप्ट पुट बनाएँ: $ MyInvocation.InvocationName इसमें और स्क्रिप्ट चलाएँ। क्या आपको स्क्रिप्ट का रास्ता मिल गया है?
शाय लेवी

@JasonMArcher - इसके बजाय क्यों? जहाँ तक मुझे पता है दोनों एक ही आउटपुट देते हैं?
मनोज्ञ

36

मैं myScript2.ps1 से myScript1.ps1 कॉल कर रहा हूं।

दोनों स्क्रिप्ट को एक ही स्थान पर मान लेने पर, पहले इस कमांड का उपयोग करके स्क्रिप्ट का स्थान प्राप्त करें:

$PSScriptRoot

और, फिर, उस स्क्रिप्ट नाम को संलग्न करें जिसे आप इस तरह से कॉल करना चाहते हैं:

& "$PSScriptRoot\myScript1.ps1"

यह काम करना चाहिए।


3
& "$PSScriptRoot\myScript1.ps1"पर्याप्त है
वीहुई गुओ

19

एक पंक्ति समाधान:

& ((Split-Path $MyInvocation.InvocationName) + "\MyScript1.ps1")

यह अच्छा है, लेकिन & '.\MyScript1.ps'अगर स्क्रिप्ट उसी निर्देशिका में रहती है तो क्यों नहीं ?
जोपीसी

3
वह वर्तमान निर्देशिका का उपयोग कर रहा है, स्क्रिप्ट निर्देशिका का नहीं। यकीन है कि वे अक्सर एक ही हैं ... लेकिन हमेशा नहीं!
noelicus

9

किसी अन्य फ़ाइल में तर्क पास करने के लिए उत्तर देने के लिए यह केवल अतिरिक्त जानकारी है

जहां आप तर्क की उम्मीद करते हैं

PrintName.ps1

Param(
    [Parameter( Mandatory = $true)]
    $printName = "Joe"    
)


Write-Host $printName

फ़ाइल को कैसे कॉल करें

Param(
    [Parameter( Mandatory = $false)]
    $name = "Joe"    
)


& ((Split-Path $MyInvocation.InvocationName) + "\PrintName.ps1") -printName $name

यदि आप कोई इनपुट प्रदान नहीं करते हैं, तो यह "जो" के लिए डिफ़ॉल्ट होगा और इसे PrintName तर्क में PrintName.ps1 फ़ाइल में तर्क के रूप में पारित किया जाएगा, जो बदले में "जो" स्ट्रिंग प्रिंट करेगा


4

आपको इसका उत्तर पहले से ही मिल गया होगा, लेकिन यहां मैं वही करता हूं।

मैं आमतौर पर अपनी स्थापना स्क्रिप्ट की शुरुआत में इस पंक्ति को रखता हूं:

if(!$PSScriptRoot){ $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent } #In case if $PSScriptRoot is empty (version of powershell V.2).  

तब मैं वर्तमान स्क्रिप्ट (पथ) के स्थान के रूप में $ PSScriptRoot चर का उपयोग कर सकता हूं, जैसे उदाहरण bellow में:

if(!$PSScriptRoot){ $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent } #In case if $PSScriptRoot is empty (version of powershell V.2).  

Try {
If (Test-Path 'C:\Program Files (x86)') {
    $ChromeInstallArgs= "/i", "$PSScriptRoot\googlechromestandaloneenterprise64_v.57.0.2987.110.msi", "/q", "/norestart", "/L*v `"C:\Windows\Logs\Google_Chrome_57.0.2987.110_Install_x64.log`""
    Start-Process -FilePath msiexec -ArgumentList $ChromeInstallArgs -Wait -ErrorAction Stop
    $Result= [System.Environment]::ExitCode
} Else {
    $ChromeInstallArgs= "/i", "$PSScriptRoot\googlechromestandaloneenterprise_v.57.0.2987.110.msi", "/q", "/norestart", "/L*v `"C:\Windows\Logs\Google_Chrome_57.0.2987.110_Install_x86.log`""
    Start-Process -FilePath msiexec -ArgumentList $ChromeInstallArgs -Wait -ErrorAction Stop
    $Result= [System.Environment]::ExitCode
    }

} ### End Try block


Catch  {
    $Result = [System.Environment]::Exitcode
    [System.Environment]::Exit($Result)
   }
[System.Environment]::Exit($Result)

आपके मामले में, आप प्रतिस्थापित कर सकते हैं

प्रारंभ-प्रक्रिया ... के साथ लाइन

Invoke-Expression $ PSScriptRoot \ ScriptName.ps1

आप Microsoft साइट पर $ MYINVOCATION और $ PSScriptRoot स्वचालित चर के बारे में अधिक पढ़ सकते हैं: https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.core/about/about_automatic_variables


4

कॉल करने वाले के रूप में उसी फ़ोल्डर (या सबफ़ोल्डर) में आसानी से स्क्रिप्ट फ़ाइल निष्पादित करने के लिए आप इसका उपयोग कर सकते हैं:

# Get full path to the script:
$ScriptRoute = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($PSScriptRoot, "Scriptname.ps1"))

# Execute script at location:
&"$ScriptRoute"

3

मुझे इससे समस्या थी। $MyInvocationहालांकि मैंने इसे ठीक करने के लिए किसी भी चतुर सामान का उपयोग नहीं किया । यदि आप किसी स्क्रिप्ट फ़ाइल पर राइट क्लिक करके ISE को खोलते हैं और चयन करते हैं, editतो ISE के भीतर से दूसरी स्क्रिप्ट खोलें आप केवल सामान्य का उपयोग करके एक से दूसरे को आमंत्रित कर सकते हैं । \ script.ps1 सिंटैक्स। मेरा अनुमान है कि ISE में करंट फ़ोल्डर की धारणा है और इसे इस तरह से खोलना स्क्रिप्ट के फ़ोल्डर में करंट फोल्डर को सेट करता है। जब मैं एक स्क्रिप्ट को सामान्य उपयोग में दूसरे से लेता हूं , जिसका मैं उपयोग करता हूं । \ script.ps1 , IMO स्क्रिप्ट को केवल ISE ​​में ठीक से काम करने के लिए इसे संशोधित करना गलत है ...


2

मुझे इसी तरह की समस्या थी और इसे इस तरह से हल किया।

मेरी कार्य निर्देशिका एक सामान्य स्क्रिप्ट फ़ोल्डर और सर्वर रूट में समान स्क्रिप्ट फ़ोल्डर है, मुझे विशेष स्क्रिप्ट फ़ोल्डर (जो सामान्य स्क्रिप्ट को विशेष समस्या के पैरामीटर के साथ कॉल करने की आवश्यकता है) को कॉल करने की आवश्यकता है। इसलिए वर्किंग डायरेक्टरी इस तरह है

\Nico\Scripts\Script1.ps1
             \Script2.ps1
      \Problem1\Solution1.ps1
               \ParameterForSolution1.config
      \Problem2\Solution2.ps1
               \ParameterForSolution2.config

Solutions1 और Solutions2 ने S1 लिपियों फ़ोल्डर में PS1 को पैरामीटर पैरामीटर में संग्रहीत पैरामीटर लोड किया है। तो अधिकार में ISE मैं इस कमांड चलाते हैं

.\Nico\Problem1\Solution1.PS1

और Solution1.PS1 के अंदर का कोड है:

# This is the path where my script is running
$path = split-path -parent $MyInvocation.MyCommand.Definition

# Change to root dir
cd "$path\..\.."

$script = ".\Script\Script1.PS1"

$parametro = "Problem1\ParameterForSolution1.config"
# Another set of parameter Script1.PS1 can receive for debuggin porpuose
$parametro +=' -verbose'

Invoke-Expression "$script $parametro"

2

मैं विचार के लिए अपना उदाहरण प्रस्तुत करता हूं। यह है कि मैं अपने द्वारा बनाए गए टूल में कंट्रोलर स्क्रिप्ट से कुछ कोड कहता हूं। स्क्रिप्ट जो काम करते हैं उन्हें मापदंडों को भी स्वीकार करने की आवश्यकता होती है, इसलिए यह उदाहरण दिखाता है कि उन्हें कैसे पारित किया जाए। यह मानती है कि स्क्रिप्ट को कॉल किया जा रहा है उसी निर्देशिका में है जो नियंत्रक स्क्रिप्ट (कॉल करने वाली स्क्रिप्ट) है।

[CmdletBinding()]
param (
[Parameter(Mandatory = $true)]
[string[]]
$Computername,

[Parameter(Mandatory = $true)]
[DateTime]
$StartTime,

[Parameter(Mandatory = $true)]
[DateTime]
$EndTime
)

$ZAEventLogDataSplat = @{
    "Computername" = $Computername
    "StartTime"    = $StartTime
    "EndTime"      = $EndTime
}

& "$PSScriptRoot\Get-ZAEventLogData.ps1" @ZAEventLogDataSplat

ऊपर एक नियंत्रक स्क्रिप्ट है जो 3 मापदंडों को स्वीकार करता है। इन्हें परम ब्लॉक में परिभाषित किया गया है। नियंत्रक स्क्रिप्ट तब Get-ZAEventLogData.ps1 नामक स्क्रिप्ट को कॉल करती है। उदाहरण के लिए, यह स्क्रिप्ट भी उन्हीं 3 मापदंडों को स्वीकार करती है। जब नियंत्रक स्क्रिप्ट उस स्क्रिप्ट को कॉल करता है जो काम करता है, तो इसे कॉल करने और मापदंडों को पास करने की आवश्यकता होती है। ऊपर दिखाया गया है कि मैं इसे कैसे दिखावा करता हूँ।


1

आप अपनी स्क्रिप्ट्स के अंदर PowerShell अंतर्निहित स्क्रिप्ट कैसे चलाते हैं?

आप अंतर्निहित स्क्रिप्ट का उपयोग कैसे करते हैं

Get-Location
pwd
ls
dir
split-path
::etc...

वे आपके कंप्यूटर द्वारा चलाए जाते हैं, स्वचालित रूप से स्क्रिप्ट के पथ की जाँच करते हैं।

इसी तरह, मैं स्क्रिप्ट-ब्लॉक में स्क्रिप्ट का नाम डालकर अपनी कस्टम स्क्रिप्ट चला सकता हूं

::sid.ps1 is a PS script I made to find the SID of any user
::it takes one argument, that argument would be the username
echo $(sid.ps1 jowers)


(returns something like)> S-X-X-XXXXXXXX-XXXXXXXXXX-XXX-XXXX


$(sid.ps1 jowers).Replace("S","X")

(returns same as above but with X instead of S)

पावरशेल कमांड लाइन पर जाएं और टाइप करें

> $profile

यह फ़ाइल को पथ को लौटाएगा जो हमारी पॉवरशेल कमांड लाइन ऐप को खोलने पर हर बार निष्पादित करेगी।

यह इस तरह दिखेगा

C:\Users\jowers\OneDrive\Documents\WindowsPowerShell\Microsoft.PowerShellISE_profile.ps1

दस्तावेज़ों पर जाएं और देखें कि क्या आपके पास पहले से ही एक WindowsPowerShell निर्देशिका है। मैंने ऐसा नहीं किया

> cd \Users\jowers\Documents
> mkdir WindowsPowerShell
> cd WindowsPowerShell
> type file > Microsoft.PowerShellISE_profile.ps1

हमने अब वह स्क्रिप्ट बनाई है, जो हर बार लॉन्च होने पर हम PowerShell ऐप खोलेंगे।

हमने जो कारण किया वह यह था कि हम अपने स्वयं के फोल्डर को जोड़ सकें, जो हमारी सभी कस्टम स्क्रिप्ट को पकड़ सके। चलो उस फ़ोल्डर को बनाते हैं और मैं इसे निर्देशिका के बाद "बिन" नाम दूंगा कि मैक / लिनक्स इसकी स्क्रिप्टों को पकड़ता है।

> mkdir \Users\jowers\Bin

अब हम चाहते हैं कि $env:pathजब भी हम एप्लिकेशन को खोलें तो वह WindowsPowerShellडायरेक्टरी हमारे वैरिएबल में जुड़ जाए इसलिए डायरेक्टरी में वापस जाएं और

> start Microsoft.PowerShellISE_profile.ps1

फिर इसे जोड़ें

$env:path += ";\Users\jowers\Bin"

अब शेल स्वचालित रूप से आपकी कमांडों को ढूंढ लेगा, जब तक आप अपनी स्क्रिप्ट को उस "बिन" निर्देशिका में सहेजते हैं।

पॉवरशेल को पुनः लोड करें और इसे निष्पादित करने वाली पहली स्क्रिप्ट्स में से एक होनी चाहिए।

अपने पथ चर में अपनी नई निर्देशिका देखने के लिए पुनः लोड करने के बाद कमांड लाइन पर इसे चलाएं:

> $env:Path

अब हम अपनी स्क्रिप्ट को कमांड लाइन से या किसी अन्य स्क्रिप्ट के भीतर से इस तरह से कॉल कर सकते हैं:

$(customScript.ps1 arg1 arg2 ...)

जैसा कि आप देखते हैं कि हमें .ps1विस्तार के साथ उन्हें तब तक बुलाना चाहिए जब तक हम उनके लिए उपनाम नहीं बनाते हैं। अगर हम फैंसला करना चाहते हैं।


वाह, इसके लिए धन्यवाद, यहां बहुत कुछ है। लेकिन यहां 9 अन्य उत्तर पहले से ही हैं। यह कैसे भिन्न होता है? यह क्या अतिरिक्त जानकारी प्रदान कर रहा है?
स्टीफन राउच

ऐसा करने से हम अपनी कस्टम-लिपियों को अन्य स्क्रिप्ट्स के अंदर उपयोग कर सकते हैं - उसी तरह जैसे हमारी स्क्रिप्ट्स के अंदर बिल्ट-इन स्क्रिप्ट्स का उपयोग किया जाता है। ऐसा करें और जब तक आप अपनी स्क्रिप्ट को उस निर्देशिका में सहेजते हैं, जिसे आप अपने पथ में रखते हैं, तो कंप्यूटर स्वचालित रूप से कस्टम-स्क्रिप्ट का पथ खोज लेगा जब आप इसे कमांड लाइन पर या किसी अन्य स्क्रिप्ट में उपयोग करते हैं
टायलर कर्टिस जॉवर्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.