web-dev-qa-db-fra.com

Test si la valeur de registre existe

Dans mon script powershell, je crée une entrée de registre pour chaque élément sur lequel je lance le script et j'aimerais stocker des informations supplémentaires sur chaque élément du registre (si vous spécifiez des paramètres facultatifs une fois, utilisez par défaut ces paramètres à l'avenir).

Le problème que j'ai rencontré est que je dois exécuter Test-RegistryValue (comme ici ) mais cela ne semble pas faire l'affaire (il retourne false même si l'entrée est existante) . J'ai essayé de " construire sur le dessus "et la seule chose que je suis venu est ceci:

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
    }
}

Malheureusement, cela ne fait pas ce dont j'ai besoin, car il semble qu'il sélectionne toujours une valeur (première?) Dans la clé de registre.

Quelqu'un a une idée de comment faire cela? Cela semble trop demander d'écrire du code managé pour cela ...

34
Newanja

Personnellement, je n'aime pas que les fonctions de test aient une chance de générer des erreurs, alors voici ce que je ferais. Cette fonction sert également de filtre que vous pouvez utiliser pour filtrer une liste de clés de registre afin de ne conserver que celles qui possèdent une clé donnée.

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
        }
    }
}
26
JasonMArcher

Le module Carbon PowerShell a une fonction Test-RegistryKeyValue qui effectuera cette vérification pour vous. (Divulgation: je suis le propriétaire/responsable de Carbon.)

Vous devez d'abord vérifier que la clé de registre existe. Vous devez alors gérer si la clé de registre n'a pas de valeurs. La plupart des exemples ici testent en réalité la valeur elle-même, au lieu de l’existence de la valeur. Cela renverra de faux négatifs si une valeur est vide ou nulle. Au lieu de cela, vous devez vérifier si une propriété pour la valeur existe réellement sur l'objet renvoyé par Get-ItemProperty.

Voici le code actuel du module 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
    }

}
11
Aaron Jensen

Probablement un problème avec les chaînes ayant des espaces. Voici une version nettoyée qui fonctionne pour moi:

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
}
5
Bacon Bits

Je voudrais aller avec la fonction Get-RegistryValue. En fait, il obtient les valeurs demandées (de sorte qu'il ne peut être utilisé que pour les tests). Dans la mesure où les valeurs de registre ne peuvent pas être nulles, nous pouvons utiliser le résultat nul comme signe d'une valeur manquante. La fonction de test pure Test-RegistryValue est également fournie.

# 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 }

SORTIE:

True
54
False
missing value
4
Roman Kuzmin

Bon mot:

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

Ma version, qui correspond au texte exact de l'exception interceptée ..__, retournera true s'il s'agit d'une exception différente mais fonctionne pour ce cas simple De plus, Get-ItemPropertyValue est une nouveauté de 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}
}
1
4x0v7

La meilleure façon de vérifier si une valeur de registre existe est de faire cela - de vérifier son existence. Ceci est un one-line, même si c'est un peu difficile à lire.

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

Si vous recherchez réellement ses données , vous rencontrez un problème avec la façon dont Powershell interprète 0.

1
Paul Williams
$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"
}
1
Pedro Lobito

Ma version:

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

Cela fonctionne pour moi:

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
    }
}
0
Ocaso Protal

J'ai pris la Méthodologie de Carbon ci-dessus et rationalisé le code en une fonction plus petite, cela fonctionne très bien pour moi.

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

Le test -not devrait se déclencher si une propriété n'existe pas:

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