从阵列列出信息的简便方法

时间:2015-05-04 22:18:31

标签: arrays powershell

我有下面的代码检查注册表中的条目(超过20个),如果它不存在,它会创建一个注册表项并将其添加到数组中。 之后我需要检查数组中的所有名称到我的其他数组,如果匹配,我需要它从我的第二个数组中提取信息并在屏幕上显示它(日志位置,注册表位置等)。但是,如果不写非常长的if语句,就无法确定如何匹配数组并在屏幕上写入。

有谁知道这样做的好方法?

提前致谢!

$Reg = "HKLM:\Software\"
$NeedtoCheck = @()
$testing = @("Test1Name","Test2Name", "Test3Name")
$allTests = @(
$Test1 = @{
Name = "Test1"
Logfile = "C:\Checking\test1.log"
Version = "16"
RegName = "test1Nameinfo*"
Installname = "InstallTest1"
UninstallName = "UninstallTest1"
},
$Test2 = @{
Name = "Test"
Logfile = "C:\test2.log"
Version = "7"
RegName = "test2Nameinfo*"
Installname = "InstallTest2"
UninstallName = "UninstallTest2"
},
$Test3 = @{
Name = "Test3"
Logfile = "C:\Temp\Checkhere\test3.log"
Version = "99"
RegName = "test3Nameinfo*"
Installname = "InstallTest3"
UninstallName = "UninstallTest3"
}


    $Test1Name = $Test1.name 
    $Test1Logfile = $Test1.Logfile 
    $Test1Version = $Test1.Version
    $Test1RegName = $Test1.RegName 
    $Test1Install = $Test1.InstallName 
    $Test1Uninstall = $Test1.UninstallName 

    $Test2Name = $Test2.name 
    $Test2Logfile = $Test2.Logfile 
    $Test2Version = $Test2.Version
    $Test2RegName = $Test2.RegName 
    $Test2Install = $Test2.InstallName 
    $Test2Uninstall = $Test2.UninstallName 

    $Test3Name = $Test3.name 
    $Test3Logfile = $Test3.Logfile 
    $Test3Version = $Test3.Version
    $Test3RegName = $Test3.RegName 
    $Test3Install = $Test3.InstallName 
    $Test3Uninstall = $Test3.UninstallName  

Foreach($Test in $testing){
$Key = (Get-Item "Reg").getvalue("$Test")
IF($Key -eq $null)
{
    New-Itemproperty -path "HKLM:\Software\" -value "Check" -PropertyType string -name $Test -Force -ErrorAction SilentlyContinue
    Write-Host "$Test created"
    $Needtocheck += $Test

}
ELSEIF($key -eq "Check")
{
    $Needtocheck += $Test
}

ELSE
{
    Write-Host "$Test already Checked"
}
}

Foreach($item in $NeedtoCheck)
{
If($item -match $Test1Name)
{
    Write-Host "$Test1Name info"
    Write-host "$Test1Name`
    $Test1Logfile`  
    $Test1Version`
    $Test1RegName` 
    $Test1Install`  
    $Test1Uninstall`
}

Else
{
    Write-Host "Not in the list"
}
}
 ....

3 个答案:

答案 0 :(得分:1)

这段代码说实话并没有多大意义。如果您想要设置20个检查,然后只运行某些检查,那很好,但您真的不需要额外的交叉检查来引用一个阵列对另一个阵列,并重新定义像您这样的事情为每个哈希表中的每个值分配变量时。就个人而言,我制作的对象不是哈希表,但这就是我。实际上,甚至可能更好,使用所有可用的测试制作哈希表,然后为值创建一个具有所需属性的对象。哦,是的,这是要走的路,但需要一点点重写。看看这个......

$Reg = 'HKLM:\Software\'
$NeedtoCheck = @()
$testing = @('Test2','Test1','NotATest')

#Define Tests
$AllTests = @{'Test1' = [PSCustomObject]@{
Name = "Test1"
Logfile = "C:\Checking\test1.log"
Version = "16"
RegName = "test1Nameinfo*"
Installname = "InstallTest1"
UninstallName = "UninstallTest1"
}
'Test2' = [PSCustomObject]@{
Name = "Test"
Logfile = "C:\test2.log"
Version = "7"
RegName = "test2Nameinfo*"
Installname = "InstallTest2"
UninstallName = "UninstallTest2"
}
'Test3' = [PSCustomObject]@{
Name = "Test3"
Logfile = "C:\Temp\Checkhere\test3.log"
Version = "99"
RegName = "test3Nameinfo*"
Installname = "InstallTest3"
UnnstallName = "UninstallTest3"
}
}
#$allTests = @($Test1,$Test2,$Test3)

Foreach($Test in $Testing){
    If($Test -in $allTests.Keys){
        $Key = (Get-Item $Reg).getvalue($AllTests[$Test].RegName)
        Switch($Key){
            #Case - Key not there
            {[string]::IsNullOrEmpty($_)}{
                New-Itemproperty -path "HKLM:\Software\" -value "Check" -PropertyType string -name $AllTests[$Test].RegName -Force -ErrorAction SilentlyContinue
                Write-Host "`n$Test created"
                Write-Host "`n$Test info:"
                Write-host $allTests[$test].Name
                Write-host $allTests[$test].LogFile
                Write-host $allTests[$test].Version
                Write-host $allTests[$test].RegName
                Write-host $allTests[$test].Installname
                Write-host $allTests[$test].Uninstallname
            }
            #Case - Key = 'Check'
            {$_ -eq "Check"}{
                Write-Host "`n$Test info:`n"
                Write-host $allTests[$test].Name
                Write-host $allTests[$test].LogFile
                Write-host $allTests[$test].Version
                Write-host $allTests[$test].RegName
                Write-host $allTests[$test].Installname
                Write-host $allTests[$test].Uninstallname
            }
            #Default - Key exists and does not need to be checked
            default {
                Write-Host "`n$Test already Checked"
            }
        }
    }Else{
        Write-Host "`n$Test not in list"
    }
}

这应该做你以前做过的事情,内置的回复和检查。另外,这并没有重复努力。此外,它允许您根据需要命名测试,并具有与该名称关联之前的所有属性。或者,您可以为每个测试运行添加一个成员,例如'状态',并将其设置为Created,Check或Valid,然后您可以稍后过滤$AllTests并查找具有Status属性的条目,如果您需要其他报告,请对其进行过滤。

答案 1 :(得分:0)

如果我理解你的要求,你可以过滤掉你想要检查的测试:

$Needtocheck | Where {$_ -in $testing} | 
    Foreach {... do something for NeedToCheck tests that existing in $testing ... }

答案 2 :(得分:0)

由于存在语法错误,我不得不更改几段代码。猜测大多数是试图为我们创建一些示例代码。我在代码中有很多注释,但除此之外我还会解释一些。

$Reg = "HKLM:\Software\"
$testing = "Test1","Test2", "Test3"
$allTests = @(
    New-Object -TypeName PSCustomObject -Property @{
        Name = "Test1"
        Logfile = "C:\Checking\test1.log"
        Version = "16"
        RegName = "test1Nameinfo*"
        Installname = "InstallTest1"
        UninstallName = "UninstallTest1"
    }
    New-Object -TypeName PSCustomObject -Property @{
        Name = "Test2"
        Logfile = "C:\test2.log"
        Version = "7"
        RegName = "test2Nameinfo*"
        Installname = "InstallTest2"
        UninstallName = "UninstallTest2"
    }
    New-Object -TypeName PSCustomObject -Property @{
        Name = "Test3"
        Logfile = "C:\Temp\Checkhere\test3.log"
        Version = "99"
        RegName = "test3Nameinfo*"
        Installname = "InstallTest3"
        UninstallName = "UninstallTest3"
    }
)

$passed = $testing | ForEach-Object{
    # Changed the for construct to better allow output. Added the next line to make the rest of the code the same. 
    $test = $_
    $Key = (Get-Item $Reg).getvalue($Test)
    If($Key -eq $null){
        # New-Itemproperty creates output. Cast that to void to keep it out of $passed 
        [void](New-ItemProperty -path "HKLM:\Software\" -value "Check" -PropertyType string -name $Test -Force -ErrorAction SilentlyContinue)
        Write-Host "$Test created"

        # Send this test to output
        Write-Output $Test
    } Elseif ($key -eq "Check")
    {
        # Send this test to output
        Write-Output $Test
    } Else {
        Write-Host "$Test already Checked"
    }
} 

$allTests | Where-Object{$passed -contains $_.Name}

我们在$testing中运行所有值,如果已创建或已经创建了一个"已选中"然后我们将它发送到填充变量$passed的管道。我们采用$allTests并过滤掉每个匹配的测试。