Tester si la valeur de registre existe

dans mon script powershell, je crée une entrée de Registre pour chaque élément sur lequel j'exécute script et je voudrais stocker des informations supplémentaires sur chaque élément dans le Registre (si vous spécifiez des paramètres optionnels une fois, puis par défaut utiliser ces paramètres dans le futur).

le problème que j'ai rencontré est que j'ai besoin d'effectuer Test-RegistryValue (comme ici), mais il ne semble pas faire l'affaire (elle retourne false, même si l'entrée existe). J'ai essayé de "tirer dessus" et seule chose que j'ai trouvé est:

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

que malheureusement aussi ne fait pas ce dont j'ai besoin comme il semble qu'il sélectionne toujours certains (d'abord?) la valeur de la clé de registre.

quelqu'un a idée de comment faire cela? Il semble juste trop d'écrire le code géré pour cela...

30
demandé sur Nick 2011-04-13 16:09:06

12 réponses

personnellement, je n'aime pas que les fonctions de test aient une chance de recracher des erreurs, donc voici ce que je ferais. Cette fonction sert aussi de filtre que vous pouvez utiliser pour filtrer une liste de clés de registre afin de garder uniquement ceux qui ont une certaine touche.

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
        }
    }
}
25
répondu JasonMArcher 2011-04-13 22:29:50

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

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

voici le code, tel qu'il est aujourd'hui, 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
répondu Aaron Jensen 2016-03-27 20:02:08

Probablement un problème avec chaînes avoir 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
répondu Bacon Bits 2011-04-13 13:04:25

je voudrais aller avec la fonction Get-RegistryValue. En fait, il obtient des valeurs (de sorte qu'il peut être utilisé non seulement pour les tests). Dans la mesure où les valeurs de Registre ne peuvent pas être nulles, nous pouvons utiliser le résultat null comme signe d'une valeur manquante. La fonction de test pure Test-RegistryValue est également fourni.

# 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
répondu Roman Kuzmin 2011-04-13 12:45:08

One-liner:

$valueExists = (Get-Item $regKeyPath -EA Ignore).Property -contains $regValueName
2
répondu Bronx 2017-02-27 21:05:50

ma version, correspondant au texte exact de l'exception capturée. Il retournera vrai si c'est une exception différente mais fonctionne pour ce cas simple. Aussi Get-ItemPropertyValue est nouveau dans 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
répondu 4x0v7 2016-06-09 09:45:41

La meilleure façon de tester si une valeur de registre existe, c'est pour faire juste cela - test de son existence. C'est un livre unique, même si c'est un peu difficile à lire.

PS C:> (Get-ItemProperty $regkey).PSObject.Propriétés.Nom-contient $nom

Si vous regardez à sa , puis vous tombez dans la complication de la façon dont Powershell interprète 0.

1
répondu Paul Williams 2017-05-11 16:57:48
$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
répondu Pedro Lobito 2017-12-02 04:52:29

-not test doit 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
répondu Torbjörn Bergstedt 2011-04-13 12:39:27

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
répondu Ocaso Protal 2011-04-13 12:47:48

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
répondu braxlan 2016-02-18 08:37:14

j'ai pris la méthodologie de Carbon ci-dessus, et j'ai simplifié 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
répondu David Vawter 2016-10-12 19:37:44