【问题标题】:Powershell: Nested For Loops, returning 1 object from functionPowershell:嵌套 For 循环,从函数返回 1 个对象
【发布时间】:2014-01-07 02:06:42
【问题描述】:

我正在尝试读取注册表项、属性和值,并能够调用该函数来创建一个 xml 文件,然后是 XML 文件中的元素。

我的注册表项看起来像:

HKCU\Software\TEX\库\... ...键1 道具1,价值1 道具2,价值2 ...键2 道具1,价值1 道具2,价值2 道具 3,价值 3 ...键3 道具1,价值1 ...Key4...等

每个键包含 1 个或多个属性及其各自的值。

key(n) 表示 xml 文件名(key1.xml、key2.xml、key3.xml 等...) 属性和值表示 xml 文件中的元素。

该函数在一个函数内部调用,该函数使用其元素创建 xml 文件。到目前为止,我已经创建了 3 个文件,但最终每个文件都包含所有键的所有属性和值。我需要为每个 xml 文件制定一种仅包含其各自属性和值的方法。我相信诀窍在于这个函数如何返回它的数据。我正在努力让它返回一个包含来自两个循环的累积数据的单个对象。根据对另一个论坛成员的问题here 的建议,我提出了以下建议:

function Get-RegValue ([string]$regPath){

       $regProp = (Get-ChildItem $regPath) 
       $scNameArray = @()
       $scRegValueArray = @()
       $scRegPropArray = @()
# Key loop
       foreach ($subKey in $regProp){
           $subKeyPath = $subKey.PSPath
           $prop = $subKey.Property
           $scName = $subkey.PSChildName
           $scNameArray += $scName
# Property & value loop           
          foreach($value in $prop){ # | Select-Object $scIndex.ToString() -Unique 
                $regValue = (Get-ItemProperty $subKeyPath).$value
                $scRegValueArray += $value
                $scRegPropArray += $regValue
           }
       }

 New-Object PSObject -Property @{
                        RegKey=$scNameArray
                        RegValue=$scRegPropArray
                        RegProperty=$scRegValueArray
                }
 } 

这给了我一个包含三个数组的对象,每个属性一个。我可以像这样“扩展”每个对象的属性:

$obj = Get-RegValue -regPath $regPath

$obj.RegKey
$obj.RegProperty
$obj.RegValue

但是,为了让这个函数在创建 xml 文件的函数中工作,我想我需要能够做这样的事情:

(Pseudo)
foreach($key in $obj.RegKey){
  $key.RegProperty 
  $key.RegValue
}

这不起作用,因为 $obj.RegKey 只允许返回“RegKey”对象。

如果这是一个数据库,我需要在对象的属性之间创建一个“关系”。也许这就是我需要做的。但是怎么做?我是在找完全错误的树吗?有更简单的方法可以实现吗?

如有任何帮助,我们将不胜感激。

非常感谢

W。

【问题讨论】:

    标签: xml loops powershell foreach nested


    【解决方案1】:

    您的问题似乎出在 Get-RegValue 函数中。它返回一个键、属性名称和值的数组,键和属性之间没有关联。

    是的,诀窍在于如何返回数据。与其自己创建和维护数组,不如只创建对象并将它们放到输出中,PowerShell 将为您生成结果数组 (http://technet.microsoft.com/en-us/library/hh847760.aspx)。

    您可以使用以下代码创建一个对象数组(哈希表),其中包含文件名(键)并与它们相关联的属性:

    Function Get-SubItem([string]$RegistryPath)
    {
        Get-ChildItem -Path $RegistryPath | % {
            $key = @{}
            $key.FileName = $_.PSChildName
            $key.Property = @{}
            foreach ($name in $_.Property) 
            {
                $key.Property.Add($name, $_.GetValue($name))
            };
            $key
        }
    }
    
    Get-SubItem -RegistryPath "HKCU:\Test" | % {
        Write-Host $_.FileName
        foreach ($entry in $_.Property.GetEnumerator()) 
        {
            Write-Host ("`t{0} - {1}" -f $entry.Key, $entry.Value)
        }
    }
    

    希望这会有所帮助。

    【讨论】:

    • 抱歉回复延迟。我没有收到电子邮件通知我答复。非常感谢列夫根。工作一种享受。我从 Create-Shortcut 函数内部调用 Get-SubItem 函数。一旦项目完全启动并运行,我将在我的博客上记录并在此处更新。
    • 如果能在博客上获得一个链接,看看它是如何工作的,会很有趣))。祝项目顺利!
    【解决方案2】:

    您可以使用for 循环而不是foreach 循环,从而通过使用数组索引在项目之间创建元关系:

    for ($i = 0; $i -lt ($obj.regkey).count; $i++) {
        $obj.RegKey[$i]
        $obj.RegValue[$i]
        $obj.RegProperty[$i]
    }
    

    【讨论】:

    • 瓦西里,感谢您的回复。 Levgen 的解决方案对我有用,但我对您的解决方案很感兴趣,一定会尝试并在这里反馈。再次感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-27
    • 2020-01-02
    • 2021-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-16
    相关资源
    最近更新 更多