Подтвердить что ты не робот

Проверить, существует ли значение реестра

В моей powershell script Я создаю одну запись реестра для каждого элемента, в котором я запускаю script, и я хотел бы сохранить некоторую дополнительную информацию об каждом элементе реестра (если вы укажете дополнительные параметры один раз, то по умолчанию используйте эти параметры в будущем).

Проблема, с которой я столкнулся, заключается в том, что мне нужно выполнить Test-RegistryValue (например, здесь), но, похоже, это не делает трюк (он возвращает false, даже если запись существует). Я попытался "опираться на него", и только я придумал следующее:

Function Test-RegistryValue($regkey, $name) 
{
    try
    {
        $exists = Get-ItemProperty $regkey $name -ErrorAction SilentlyContinue
        Write-Host "Test-RegistryValue: $exists"
        if (($exists -eq $null) -or ($exists.Length -eq 0))
        {
            return $false
        }
        else
        {
            return $true
        }
    }
    catch
    {
        return $false
    }
}

К сожалению, я также не делаю то, что мне нужно, поскольку он всегда выбирает какое-либо (первое?) значение из раздела реестра.

У кого-нибудь есть идея, как это сделать? Кажется, слишком сложно написать управляемый код для этого...

4b9b3361

Ответ 1

Лично мне не нравятся тестовые функции, имеющие шанс выплескивать ошибки, поэтому вот что я буду делать. Эта функция также дублируется как фильтр, который вы можете использовать для фильтрации списка ключей реестра, чтобы сохранить только те, у которых есть определенный ключ.

Function Test-RegistryValue {
    param(
        [Alias("PSPath")]
        [Parameter(Position = 0, Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [String]$Path
        ,
        [Parameter(Position = 1, Mandatory = $true)]
        [String]$Name
        ,
        [Switch]$PassThru
    ) 

    process {
        if (Test-Path $Path) {
            $Key = Get-Item -LiteralPath $Path
            if ($Key.GetValue($Name, $null) -ne $null) {
                if ($PassThru) {
                    Get-ItemProperty $Path $Name
                } else {
                    $true
                }
            } else {
                $false
            }
        } else {
            $false
        }
    }
}

Ответ 2

Модуль Carbon PowerShell имеет Test-RegistryKeyValue, которая проведет эту проверку для вас. (Раскрытие информации: Я являюсь владельцем/владельцем Carbon.)

Сначала необходимо проверить, существует ли ключ реестра. Затем вам придется обращаться, если ключ реестра не имеет значений. Большинство примеров здесь фактически проверяют само значение, а не существование значения. Это вернет ложные отрицания, если значение пустое или пустое. Вместо этого вам нужно проверить, действительно ли свойство для значения существует для объекта, возвращаемого Get-ItemProperty.

Здесь код, как и сегодня, из модуля Carbon:

function Test-RegistryKeyValue
{
    <#
    .SYNOPSIS
    Tests if a registry value exists.

    .DESCRIPTION
    The usual ways for checking if a registry value exists don't handle when a value simply has an empty or null value.  This function actually checks if a key has a value with a given name.

    .EXAMPLE
    Test-RegistryKeyValue -Path 'hklm:\Software\Carbon\Test' -Name 'Title'

    Returns `True` if `hklm:\Software\Carbon\Test` contains a value named 'Title'.  `False` otherwise.
    #>
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [string]
        # The path to the registry key where the value should be set.  Will be created if it doesn't exist.
        $Path,

        [Parameter(Mandatory=$true)]
        [string]
        # The name of the value being set.
        $Name
    )

    if( -not (Test-Path -Path $Path -PathType Container) )
    {
        return $false
    }

    $properties = Get-ItemProperty -Path $Path 
    if( -not $properties )
    {
        return $false
    }

    $member = Get-Member -InputObject $properties -Name $Name
    if( $member )
    {
        return $true
    }
    else
    {
        return $false
    }

}

Ответ 3

Вероятно, проблема со строками, имеющими пробелы. Вот очищенная версия, которая работает для меня:

Function Test-RegistryValue($regkey, $name) {
    $exists = Get-ItemProperty -Path "$regkey" -Name "$name" -ErrorAction SilentlyContinue
    If (($exists -ne $null) -and ($exists.Length -ne 0)) {
        Return $true
    }
    Return $false
}

Ответ 4

Я бы пошел с функцией Get-RegistryValue. Фактически он получает запрашиваемые значения (чтобы его можно было использовать не только для тестирования). Поскольку значения реестра не могут быть пустыми, мы можем использовать нулевой результат как признак недостающего значения. Также предоставляется чистая тестовая функция Test-RegistryValue.

# This function just gets $true or $false
function Test-RegistryValue($path, $name)
{
    $key = Get-Item -LiteralPath $path -ErrorAction SilentlyContinue
    $key -and $null -ne $key.GetValue($name, $null)
}

# Gets the specified registry value or $null if it is missing
function Get-RegistryValue($path, $name)
{
    $key = Get-Item -LiteralPath $path -ErrorAction SilentlyContinue
    if ($key) {
        $key.GetValue($name, $null)
    }
}

# Test existing value
Test-RegistryValue HKCU:\Console FontFamily
$val = Get-RegistryValue HKCU:\Console FontFamily
if ($val -eq $null) { 'missing value' } else { $val }

# Test missing value
Test-RegistryValue HKCU:\Console missing
$val = Get-RegistryValue HKCU:\Console missing
if ($val -eq $null) { 'missing value' } else { $val }

ВЫВОД:

True
54
False
missing value

Ответ 5

$regkeypath= "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" 
$value1 = (Get-ItemProperty $regkeypath -ErrorAction SilentlyContinue).Zoiper -eq $null 
If ($value1 -eq $False) {
Write-Host "Value Exist"
} Else {
Write-Host "The value does not exist"
}

Ответ 6

Моя версия, соответствующая точному тексту из застигнутого исключения. Он вернет true, если это другое исключение, но работает для этого простого случая. Также Get-ItemPropertyValue является новым в PS 5.0

Function Test-RegValExists($Path, $Value){
$ee = @() # Exception catcher
try{
    Get-ItemPropertyValue -Path $Path -Name $Value | Out-Null
   }
catch{$ee += $_}

    if ($ee.Exception.Message -match "Property $Value does not exist"){return $false}
else {return $true}
}

Ответ 7

Однострочник:

$valueExists = (Get-Item $regKeyPath -EA Ignore).Property -contains $regValueName

Ответ 8

Лучший способ проверить, существует ли значение реестра, - это просто проверить его существование. Это однострочный, даже если его немного читать трудно.

PS C: > (Get-ItemProperty $regkey).PSObject.Properties.Name -contains $Имя

Если вы действительно просматриваете свои данные, вы сталкиваетесь с тем, как Powershell интерпретирует 0.

Ответ 9

Тест -not должен срабатывать, если свойство не существует:

$prop = (Get-ItemProperty $regkey).$name
if (-not $prop)
{
   New-ItemProperty -Path $regkey -Name $name -Value "X"
}

Ответ 10

Это работает для меня:

Function Test-RegistryValue 
{
    param($regkey, $name)
    $exists = Get-ItemProperty "$regkey\$name" -ErrorAction SilentlyContinue
    Write-Host "Test-RegistryValue: $exists"
    if (($exists -eq $null) -or ($exists.Length -eq 0))
    {
        return $false
    }
    else
    {
        return $true
    }
}

Ответ 11

Моя версия:

Function Test-RegistryValue($Key, $Name)
{
    (Get-ChildItem (Split-Path -Parent -Path $Key) | Where-Object {$_.PSChildName -eq (Split-Path -Leaf $Key)}).Property -contains $Name
}

Ответ 12

Я взял методологию из Carbon выше и упростил код до меньшей функции, это очень хорошо для меня.

    Function Test-RegistryValue($key,$name)
    {
         if(Get-Member -InputObject (Get-ItemProperty -Path $key) -Name $name) 
         {
              return $true
         }
         return $false
    }