2013-04-17 57 views
3

我一直致力於更新我編寫的一些腳本。我仍然在學習PowerShell,所以我想回到我的舊版本,看看我能不能改進。
我偶然發現了Modules,並且非常喜歡使用它們來存儲隨後可以隨時調用的不同動作的想法。PowerShell:腳本模塊變量在ISE之外不可用

我寫了一個簡單的腳本來測試(或所以我想)。我應該提到我正在將我的模塊存儲在服務器共享中。

Write-Host "Testing for available variables" 
Write-Host "Loading Modules" 
Import-Module <path to my module on server share>.psm1 
Write-Host "" 
Write-Host "Done" 
Write-Host "Print loaded modules" 
Get-Module 
Write-Host "" 
Write-Host "Done" 
Write-Host "=================" 
Write-Host "" 
Write-Host "Printing variables" 
Write-Host "" 
Write-Host "Variable: arch: " $arch 
Write-Host "Variable: WowNode: " $WowNode 
Write-Host "" 
Write-Host "Done" 

我模塊包含

If ("${env:ProgramFiles(x86)}" -ne "") 
{ 
    $script:arch = 64 
    $script:WowNode = "\Wow6432Node\" 
} 
ELSE 
{ 
    $script:arch = 32 
    $script:WowNode = "\" 
} 

當我使用Windows PowerShell ISE的一切功能,我怎麼想它會運行我的腳本。我看到變量的內容,並正確輸出。
當我從Powershell命令行窗口運行我的腳本時,模塊被加載,但變量是空白的(沒有輸出)。
我一直在挖掘谷歌,我看到的唯一可能導致這與我用來定義我的變量的範圍有關。
將它們定義爲$ script:xx將它們放到Global作用域中(我敢肯定),這使得它們在整個腳本中都可用。所以我想我正確地定義了我的變量。但我仍然沒有任何運氣。

我可能錯過了一些明顯的東西,但對於我的生活我找不到它。
有什麼建議我可以做什麼來解決這個問題?
我已經確認我正在運行PowerShell的2.0版本,因爲我讀過模塊只在版本2.0中可用。

回答

9

從我現在所能想到的(沒有測試)來看,問題在於你說的範圍。在ISE和控制檯中運行腳本是有區別的。我猜測你在ISE中運行腳本時,你打開腳本並按下運行按鈕。這將在控制檯中逐行執行腳本,如果您將它們直接鍵入控制檯。這使腳本本身在global(會話)變量作用域中運行。由於該腳本位於global中,因此您的模塊將是唯一在script範圍內運行的模塊。

但是,當您在PowerShell控制檯中運行腳本時;像:

PS > .\myscript.ps1 

然後你的腳本在script範圍運行(當腳本完成每一個變量被刪除)。現在,模塊將運行在它自己的script範圍內,在您的主腳本運行的範圍之下。當模塊導入完成時,模塊的script範圍被刪除,並且您的主腳本將查看它自己的範圍,您變量不存在。

Global (session) 
- Script (mainscript) 
    - Script (module) 
    #Module completes, and scope is deleted 
    #You look for $script:arch , which was actually deleted right above. 
    #Powershell searches through the mainscript's scope, but finds nothing. 

爲了解決這個問題,嘗試在global(會話)範圍存儲的值,這樣$global:arch。指定global作爲創建變量(必需)時的範圍,以及從中讀取時(建議)。

+1

謝謝!你100%正確。起初,我不明白它,直到我讀你的第二個代碼塊,它是有道理的。我現在明白爲什麼我的變量不可用。我將模塊中的變量重新定義爲$ global:arch,並重新測試了我的小測試腳本,現在我可以打印出變量的內容。對自己瘋狂,因爲不能早點理解!再次感謝您解釋它! – bourne

+2

超級解釋,順便說一句! –

+1

我發現還有另一種方法可以做到這一點。您可以將變量聲明爲正常「$ var1 = test」。然後在您的導入語句中,您可以使用-Global選項,並且變量應該可用:「Import-Module-Global 」。我同意Mike Shepard--絕對是一個很好的解釋! – bourne