PowerShell循环结束时清空项目

时间:2017-04-05 19:24:37

标签: powershell registry

我正在使用我问题末尾列出的脚本(this script的修改版本)来搜索注册表。输出大多是正确的,但最后我得到一组额外的“Key:Reason:Details:”行。这是输出,显示最后一个正确的块,然后是空块:

VERBOSE: Key: 'HKEY_CURRENT_USER\SOFTWARE\blahblah\ProgId'
Key     : 'HKEY_CURRENT_USER\SOFTWARE\blahblah\ProgId'
Reason  : ValueData
Details : {'foo.Class1'}

VERBOSE: Key: 'HKEY_CURRENT_USER\SOFTWARE\blahblah\Version'
VERBOSE: Key: 'HKEY_CURRENT_USER\SOFTWARE\blahblah\VersionIndependentProgID'
Key     :
Reason  :
Details :

我无法弄清楚导致空白行的原因。我的脚本测试以确保该项不为null(使用At the top, i is 9 Numbers now: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] At the bottom i is 10 ),但无论如何都会忽略该行。同样,我知道旧版本的PowerShell没有测试null,但我使用的是PS 5。

脚本在这里(减去概要和描述,我无法在这里正确格式化):

if ($key)

并且示例调用在这里:

[CmdletBinding()]
Param(
    [Parameter(Mandatory, Position=0, ValueFromPipelineByPropertyName)]
    [Alias("PsPath")]
    # Registry path to search
    [string[]] $Path,
    # Specifies whether or not all subkeys should also be searched
    [switch] $Recurse,
    [Parameter(ParameterSetName="SingleSearchString", Mandatory)]
    # A regular expression that will be checked against key names, value
    # names, and value data (depending on the specified switches)
    [string] $SearchRegex,
    [Parameter(ParameterSetName="SingleSearchString")]
    # When the -SearchRegex parameter is used, this switch means that key
    # names will be tested (if none of the three switches are used, keys
    # will be tested)
    [switch] $KeyName,
    [Parameter(ParameterSetName="SingleSearchString")]
    # When the -SearchRegex parameter is used, this switch means that the
    # value names will be tested (if none of the three switches are used,
    # value names will be tested)
    [switch] $ValueName,
    [Parameter(ParameterSetName="SingleSearchString")]
    # When the -SearchRegex parameter is used, this switch means that the
    # value data will be tested (if none of the three switches are used,
    # value data will be tested)
    [switch] $ValueData,
    [Parameter(ParameterSetName="MultipleSearchStrings")]
    # Specifies a regex that will be checked against key names only
    [string] $KeyNameRegex,
    [Parameter(ParameterSetName="MultipleSearchStrings")]
    # Specifies a regex that will be checked against value names only
    [string] $ValueNameRegex,
    [Parameter(ParameterSetName="MultipleSearchStrings")]
    # Specifies a regex that will be checked against value data only
    [string] $ValueDataRegex
)

Begin {
    switch ($PSCmdlet.ParameterSetName) {
        SingleSearchString {
            $NoSwitchesSpecified = -not (
                $PSBoundParameters.ContainsKey("KeyName") -or
                $PSBoundParameters.ContainsKey("ValueName") -or
                $PSBoundParameters.ContainsKey("ValueData")
            )
            if ($KeyName -or $NoSwitchesSpecified) {
                $KeyNameRegex = $SearchRegex
            }
            if ($ValueName -or $NoSwitchesSpecified) {
                $ValueNameRegex = $SearchRegex
            }
            if ($ValueData -or $NoSwitchesSpecified) {
                $ValueDataRegex = $SearchRegex
            }
        }
        MultipleSearchStrings {
            # No extra work needed
        }
    }
}

Process {
    $sw = [Diagnostics.Stopwatch]::StartNew()
    foreach ($CurrentPath in $Path) {
        Write-Verbose ("CurrentPath: {0}" -f $CurrentPath)
        try {
            Get-ChildItem $CurrentPath -Recurse:$Recurse | ForEach-Object {
                $Key = $_
                Write-Verbose ("Key: '{0}'" -f $Key.Name)
                if ($Key) {
                    if ($KeyNameRegex) {
                        #Write-Verbose ("{0}: Checking KeyNameRegex" -f $Key.Name)

                        if ($Key.PSChildName -match $KeyNameRegex) {
                            #Write-Verbose("  -> Match found! Key.PSChildname = {0}" -f $Key.PSChildName)
                            return [PSCustomObject] @{
                                Key = "'" + $Key + "'"
                                Reason = "KeyName"
                                Details = $Key.PSChildName
                            }
                        }
                    }

                    if ($ValueNameRegex) {
                        #Write-Verbose ("{0}: Checking ValueNameRegex" -f $Key.Name)

                        if ($Key.GetValueNames() -match $ValueNameRegex) {
                            $MatchingItem = ($Key.GetValueNames() | Select-String -Pattern $ValueNameRegex)
                            #Write-Verbose("  -> Matching value name found! MatchingItem = {0}" -f $MatchingItem)
                            return [PSCustomObject] @{
                                Key = "'" + $Key + "'"
                                Reason = "ValueName"
                                Details = $MatchingItem
                            }
                        }
                    }

                    if ($ValueDataRegex) {
                        #Write-Verbose ("{0}: Checking ValueDataRegex" -f $Key.Name)

                        if (($Key.GetValueNames() | % { $Key.GetValue($_) }) -match $ValueDataRegex) {
                            $MatchingItems = ($Key.GetValueNames() |
                                             % { $Key.GetValue($_) } |
                                             Where {$_ -match $valueDataRegex})
                            $NewList = @()
                            foreach ($Item in $MatchingItems) {
                                $NewList += "'$Item'"
                            }
                            #Write-Verbose("  -> Matching value data found! NewList = {0}" -f $NewList)
                            return [PSCustomObject] @{
                                Key = "'" + $Key + "'"
                                Reason = "ValueData"
                                Details = $NewList
                            }
                        }
                    }
                }
            }
        } catch {
            Write-Warning "Failure for $CurrentPath"
            Write-Warning "Details: $($_.Exception.Message)"
        }
    } # end foreach
    $sw.Stop()
    Write-Output ("Seconds elapsed: {0}" -f $sw.Elapsed.TotalSeconds)
}

0 个答案:

没有答案