[英]PowerShell: How can I pass a nested hash table to my function that accepts 3 parameters?
我創建了這個 function 但我不知道如何讓它工作。 這是代碼:
function ProgramRegistry {
param (
[Parameter(Mandatory=$false)][HashTable]$HashTable,
[Parameter(Mandatory=$false)][String]$AlertPath,
[Parameter(Mandatory=$false)][String]$AlertName,
[Parameter(Mandatory=$false)][String]$AlertValue
)
foreach ($AlertPath in $HashTable.Values){
foreach($AlertName in $HashTable.Values){
foreach($AlertValue in $HashTable.Values){
New-Item -Path $AlertPath -Force | Out-Null
New-ItemProperty -Path $AlertPath -Name $AlertName -Value $AlertValue -PropertyType DWORD -Force
}
}
}
}
$keys = [ordered]@{
key1 = @{
AlertPath = 'Path'
AlertName = 'Name'
AlertValue = 'Value'
}
key2 = @{
AlertPath = 'Path'
AlertName = 'Name'
AlertValue = 'Value'
}
# and so on...
}
ModifyRegistry @keys
ModifyRegistry -AlertPath "path" -AlertName "name" -AlertValue "value"
我希望能夠以 2 種不同的方式調用 function(如腳本所示)
我怎樣才能做到這一點?
我只想修改 function 而不是我調用它的方式。 我需要多次調用它,並希望盡可能少地調用它,就像這個ModifyRegistry @keys
。 如果 function 本身又復雜又長也沒關系,但我希望調用 function 只需要很少的代碼。 我可以重復調用 function 而不是嵌套的 hash 表,但它會重復太多代碼,這就是我想要避免的。
您可以修改您的 function 以接受哈希表的哈希表。 您只需要提供一些邏輯來檢查接收到的哈希表是否是包含具有您需要的值的其他哈希表的哈希表,或者它是否是包含您需要的值的單個哈希表。 還需要在不提供哈希表時仍然處理其他參數。 下面的示例顯示了我將如何在高級 function 中使用開始、處理和結束塊來執行此操作。 在開始塊中,我們只需要創建我們將用於篩選輸入的集合 object。 對使用管道時收到的每個輸入 object 重復處理塊。 如果直接將 arguments 提供給 function,則此過程塊將只運行一次。 我們將使用此流程塊來確定輸入對象並將其添加到我們創建的 $inputs arraylist 中。 在結束塊中,我們將對收集到的每個對象執行實際處理。
function ProgramRegistry {
[cmdletbinding()]
param (
# ValueFromPipeline attribute will allow piping hashtables to the function
[Parameter(Mandatory = $false, ValueFromPipeline)][HashTable]$HashTable,
[Parameter(Mandatory = $false)][String]$AlertPath,
[Parameter(Mandatory = $false)][String]$AlertName,
[Parameter(Mandatory = $false)][String]$AlertValue
)
begin {
# Create an arraylist to collect hashtables for later processing in end block
$inputs = [System.Collections.ArrayList]::new()
}
process {
if ($HashTable) {
if ($HashTable.ContainsKey('AlertPath')) {
# if single hashtable is received with 'AlertPath' key add to inputs for processing in end block
$inputs.Add($HashTable) | Out-Null
}
else {
foreach ($value in $HashTable.Values) {
# check if value of key is a hashtable
if ($value -is [hashtable]) {
# check if hashtable contains key "AlertPath" and if so add to $inputs for processing in end block
if ($value.ContainsKey('AlertPath')) {
$inputs.Add($value) | Out-Null
}
else {
Write-Warning "Invalid hashtable format - missing 'AlertPath' key"
}
} else {
Write-Warning "Object is not a hashtable"
}
}
}
}
else {
# process when not a hashtable by creating a hashtable and adding to $inputs
$inputs.Add(@{
AlertPath = $AlertPath
AlertName = $AlertName
AlertValue = $AlertValue
}) | Out-Null
}
}
end {
# Process hashtables collected in $inputs
foreach ($hash in $inputs) {
# your code here
[pscustomobject]@{
Path = $hash.AlertPath
Name = $hash.AlertName
Value = $hash.AlertValue
}
}
}
}
$keys = [ordered]@{
key1 = @{
AlertPath = 'Path1'
AlertName = 'Name1'
AlertValue = 'Value1'
}
key2 = @{
AlertPath = 'Path2'
AlertName = 'Name2'
AlertValue = 'Value2'
}
# and so on...
}
ProgramRegistry -HashTable $keys
# or
$keys | ProgramRegistry
# or even
ProgramRegistry -HashTable $keys.key1 #or $keys.key1 | ProgramRegistry
如果不需要流水線和高級 function,您仍然可以在沒有開始、過程和結束塊的情況下執行類似的操作。 我使用嵌套的 function 'processit' 這樣我就不必多次重復處理邏輯
function ProgramRegistry {
param (
[Parameter(Mandatory = $false)][HashTable]$HashTable,
[Parameter(Mandatory = $false)][String]$AlertPath,
[Parameter(Mandatory = $false)][String]$AlertName,
[Parameter(Mandatory = $false)][String]$AlertValue
)
# create nested function to process each hash table.
function processit {
param([hashtable]$hash)
# add processing logic here
[pscustomobject]@{
Path = $hash.AlertPath
Name = $hash.AlertName
Value = $hash.AlertValue
}
}
if ($HashTable) {
if ($HashTable.ContainsKey('AlertPath')) {
# if single hashtable is received with 'AlertPath' key process it
processit -hash $HashTable
}
else {
foreach ($value in $HashTable.Values) {
# check if value of key is a hashtable
if ($value -is [hashtable]) {
# check if hashtable contains key "AlertPath" and if so process it
if ($value.ContainsKey('AlertPath')) {
processit -hash $value
}
else {
Write-Warning "Invalid hashtable format - missing 'AlertPath' key"
}
}
else {
Write-Warning 'Object is not a hashtable'
}
}
}
}
else {
processit @{AlertPath = $AlertPath; AlertName = $AlertName; AlertValue = $AlertValue }
}
}
更新以回應您關於使用密鑰名稱作為 AlertName 的問題
function ProgramRegistry {
param (
[Parameter(Mandatory = $false)][HashTable]$HashTable,
[Parameter(Mandatory = $false)][String]$AlertPath,
[Parameter(Mandatory = $false)][String]$AlertName,
[Parameter(Mandatory = $false)][String]$AlertValue
)
# create nested function to process each hash table.
function processit {
param([hashtable]$hash)
# add processing logic here
[pscustomobject]@{
Path = $hash.AlertPath
Name = $hash.AlertName
Value = $hash.AlertValue
}
}
if ($HashTable) {
if ($HashTable.ContainsKey('AlertPath')) {
# if single hashtable is received with 'AlertPath' key process it
processit -hash $HashTable
}
else {
foreach ($item in $HashTable.GetEnumerator()) {
if ($item.Value -is [hashtable]) {
# check if the hashtable has AlertPath and AlertValue keys
if ($item.Value.ContainsKey('AlertPath') -and $item.Value.ContainsKey('AlertValue')) {
$hash = $item.Value
# check if hashtable contains an AlertName key.
if (-not $hash.ContainsKey('AlertName')){
# If not use parent key name
$hash.AlertName = $item.Key
}
processit -hash $hash
}
else {
Write-Warning "Invalid hashtable format - missing AlertPath and/or AlertValue key"
}
}
else {
Write-Warning "Item does not contain a hashtable"
}
}
}
}
else {
processit @{AlertPath = $AlertPath; AlertName = $AlertName; AlertValue = $AlertValue }
}
}
撥打電話 function
$items = @{
Alert1 = @{
AlertPath = 'Path1'
AlertValue = 'Value1'
}
Alert2 = @{
AlertPath = 'Path2'
AlertValue = 'Value2'
}
Alert3 = @{
AlertName = 'Overridden AlertName'
AlertPath = 'Path3'
AlertValue = 'Value3'
}
Alert4 = @{
AlertValue = 'Value2'
}
Alert5 = "just a string"
}
ProgramRegistry -HashTable $items
Output
WARNING: Item does not contain a hashtable
WARNING: Invalid hashtable format - missing AlertPath and/or AlertValue key
Path Name Value
---- ---- -----
Path3 Overridden AlertName Value3
Path2 Alert2 Value2
Path1 Alert1 Value1
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.