2009-04-18 77 views
15

假設您是一位系統管理員,他使用PowerShell來管理他/她系統上的很多事情。從某個目錄將所有函數加載到PowerShell中

您可能已經編寫了很多功能,可以執行您經常需要檢查的功能。但是,如果你需要大量移動,大量使用不同的機器等,則必須一次又一次地重新輸入所有功能才能使用它們。我甚至必須這樣做,每次我退出並重新啓動PowerShell出於某種原因,因爲它不會記住這些函數...

我已經寫了一個函數來爲我做這件事。我在這裏發佈,因爲我想確保它是萬無一失的。函數本身存儲在allFunctions.ps1中,這就是爲什麼我將它排除在代碼中的原因。

其基本思想是你有一個文件夾,你可以在其中存儲你所有的ps1文件,每個文件夾都包含一個函數。在PowerShell中,你去到該目錄,然後輸入:

. .\allFunctions.ps1 

該腳本的內容是這樣的:

[string]$items = Get-ChildItem -Path . -Exclude allFunctions.ps1 
$itemlist = $items.split(" ") 
foreach($item in $itemlist) 
{ 
    . $item 
} 

該腳本將首先收集在你的目錄所有文件,這意味着所有非ps1文件,你也可能在那裏。 allFunctions.ps1將被排除。

然後我根據空間分割長字符串,這是常見的分隔符。然後我用Foreach循環遍歷它,每次將函數初始化爲PowerShell。

假設你有超過100個功能,你永遠不知道你需要哪些,哪些不需要?爲什麼不把他們全部輸入而不是挑剔?

所以我想知道,這裏可能會出現什麼問題?我希望這是非常安全的,因爲我可能會使用它很多。

回答

15

將它們包含在PowerShell配置文件中,以便每次啓動PS時它們都會自動加載。

查看Windows PowerShell Profiles瞭解更多關於在哪裏可以找到您的個人資料腳本的信息。

PS默認您的配置文件到您的「我的文檔」文件夾。 Mine位於網絡驅動器上,因此在我登錄的任何位置,PowerShell指向相同的配置文件文件夾。

6

功能明智我認爲有幾種方法可以改善您的腳本。

首先,您的腳本依賴於腳本的名稱不變。雖然我不認爲你可能會改變這個劇本的名字,但你永遠不會知道幾年後你會有什麼樣的心情。相反,爲什麼不動態地計算腳本的名稱。

$scriptName = split-path -leaf $MyInvocation.MyCommand.Definition 

下一個問題是,我相信你是分裂功能將失敗,如果你曾經將目錄放在一個包含空格的路徑。它會導致像「c:\ foo bar \ baz.ps1」這樣的路徑顯示爲「c:\ foo」,「bar \ baz.ps1」。更好地移除分割,並使用get-childitem命令的枚舉。

此外,您正在對當前包含腳本的路徑進行依賴。你應該做一個明確的參數或使用包含allFunctions.ps1文件的路徑(我更喜歡後者)

這是我將使用的更新版本。

$scriptName = split-path -leaf $MyInvocation.MyCommand.Definition 
$rootPath = split-path -parent $MyInvocation.MyCommand.Definition 
$scripts = gci -re $rootPath -in *.ps1 | ?{ $_.Name -ne $scriptName } 
foreach ($item in $scripts) { 
    . $item.FullName 
} 

從安全角度來看,您必須考慮惡意用戶向目標目錄中添加壞腳本的可能性。如果他們這樣做,它會與您的allFunctions.ps1文件一起執行,並可能損壞計算機。但是在惡意用戶可以訪問文件系統的時候,他們可能會在沒有腳本的幫助下做到這一點,所以這可能是一個小問題。

+0

他似乎喜歡在PS中使用字符串進行翻譯:) – Joey 2009-04-18 17:38:55

+0

感謝您的幫助,您提到了一些好的一點。實際上,入侵的黑客可能會造成更多的傷害。 另外,約翰,這不是我喜歡PS中的字符串,我更喜歡設置變量類型,當用戶輸入一個字符串應該是的數字時,會拋出一個錯誤,而不是腳本仍然嘗試做某事用它。 – KdgDev 2009-04-18 17:41:59

+1

Get-ChildItem將返回FileInfo/DirectoryInfo對象的集合。沒辦法,你可以嘗試在那裏使用數字。 – Joey 2009-04-18 17:43:46

10

你可以用更簡單的方法來做到這一點。我在我的個人資料中有:

##------------------------------------------- 
## Load Script Libraries 
##------------------------------------------- 
Get-ChildItem ($lib_home + "*.ps1") | ForEach-Object {& (Join-Path $lib_home $_.Name)} | Out-Null 

其中$ lib_home是存儲我想要自動包含的腳本的文件夾。在這種情況下,它執行它們。所以我有腳本定義全局函數。您也可以點出它們的源代碼(將「&」替換爲「。」)。

0

簡單的解決方案:

$Path - file location 
$Name - exluded file 

Get-ChildItem -Path $Path | Where {$_.psIsContainer -eq $false}|Where { $_.Name -like "*.ps1" }|Where { $_.Name -ne $Name }|foreach-object -process {.$_.FullName}|out-null 

read all object|file only| powershell file only|exclude file $Name| run ...|out-null 
0

另一個解決方案是功能組合成一個模塊(PSM1)文件並導入與所述導入模塊命令。如上所述,您可以將Import-Module命令添加到您的配置文件中,但語法更爲簡單。

一個簡單的啓動方法是在WindowsPowerShell目錄中創建一個名爲Modules的文件夾。在該文件夾中用您的模塊名稱創建另一個文件夾。你的psm1文件保存在這裏。然後將Import-Module ModuleName.psm1添加到WindowsPowerShell目錄中的配置文件。如果您想使用其他配置文件或將您的模塊保存在其他位置,則需要相應地操作路徑。

另一個提示是對模塊文件中的每個函數使用Export-ModuleMember FunctionName。這會掩蓋您可能分發給此用戶的最終用戶的支持功能。

相關問題