{"id":353768,"date":"2024-08-30T12:14:56","date_gmt":"2024-08-30T12:14:56","guid":{"rendered":"https:\/\/www.ninjaone.com\/script-hub\/buscar-claves-de-registro\/"},"modified":"2024-10-13T19:08:37","modified_gmt":"2024-10-13T19:08:37","slug":"buscar-claves-de-registro","status":"publish","type":"script_hub","link":"https:\/\/www.ninjaone.com\/es\/script-hub\/buscar-claves-de-registro\/","title":{"rendered":"C\u00f3mo buscar claves de registro, propiedades y valores en el Registro de Windows mediante PowerShell"},"content":{"rendered":"<p>El scripting de PowerShell es una habilidad crucial para los profesionales de TI y los <a href=\"https:\/\/www.ninjaone.com\/es\/que-es-un-msp\" target=\"_blank\" rel=\"noopener\">proveedores de servicios gestionados (MSP)<\/a> que buscan agilizar sus operaciones y mejorar su <a href=\"https:\/\/www.ninjaone.com\/es\/eficiencia\" target=\"_blank\" rel=\"noopener\">eficiencia<\/a>. Uno de estos potentes scripts para buscar claves de registro est\u00e1 dise\u00f1ado para <strong>buscar<\/strong> claves de registro, propiedades o valores espec\u00edficos <strong>en el Registro de Windows.<\/strong>\u00a0Esta capacidad puede ayudar significativamente a solucionar problemas, auditar y gestionar entornos Windows, lo que la convierte en una herramienta indispensable para quienes mantienen un gran n\u00famero de sistemas.<\/p>\n<h2>Background<\/h2>\n<p>El Registro de Windows es una base de datos jer\u00e1rquica que almacena configuraciones de bajo nivel para el sistema operativo y las aplicaciones instaladas. Los profesionales de TI a menudo necesitan buscar en esta amplia base de datos para encontrar configuraciones espec\u00edficas, solucionar problemas o verificar ajustes. Las b\u00fasquedas manuales pueden ser tediosas y dar lugar a errores, sobre todo cuando se trata de claves muy anidadas. Este script automatiza el proceso, proporcionando una forma fiable y eficaz de localizar informaci\u00f3n de registro basada en criterios de b\u00fasqueda espec\u00edficos.<\/p>\n<h2>El script para buscar claves de registro<\/h2>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"powershell\">#Requires -Version 5.1\r\n\r\n&lt;#\r\n.SYNOPSIS\r\n    Find a registry key path, property or value that contains your given search text. Larger depth values may increase script runtime.\r\n.DESCRIPTION\r\n    Find a registry key path, property or value that contains your given search text. Larger depth values may increase script runtime.\r\n.EXAMPLE\r\n    -RootKey \"HKEY_USERS\" -SearchPath \"*\\Software\" -Search \"Microsoft\" -Path -Property -Value\r\n\r\n    WARNING: Matching registry path names found!\r\n    WARNING: Matching registry properties found!\r\n    WARNING: Matching registry key values found!\r\n\r\n\r\n    Path     : HKEY_USERS\\.DEFAULT\\Software\\AppDataLow\\Software\\Microsoft\r\n    Property : N\/A\r\n    Value    : N\/A\r\n\r\n    Path     : HKEY_USERS\\.DEFAULT\\Software\\Classes\\Local Settings\\MrtCache\\C:%5CProgram Files%5CWindowsApps%5CClipchamp.Clipchamp_2.9.1.0_neutral__yxz26nhyzhsrt%5Cresources.pri\\1da6c1775fdf538\\a37dfe62\r\n    Property : @{C:\\Program Files\\WindowsApps\\Clipchamp.Clipchamp_2.9.1.0_neutral__yxz26nhyzhsrt\\resources.pri? ms-resource:\/\/\/resources\/Clipchamp\/AppName}\r\n    Value    : Microsoft Clipchamp\r\n\r\n    Path     : HKEY_USERS\\.DEFAULT\\Software\\Classes\\Local Settings\\MrtCache\\C:%5CProgram Files%5CWindowsApps%5CMicrosoft.BingNews_4.55.62231.0_x64__8wekyb3d8bbwe%5Cresources.pri\\1da6c1719ed8ee6\\a37dfe62\r\n    Property : @{C:\\Program Files\\WindowsApps\\Microsoft.BingNews_4.55.62231.0_x64__8wekyb3d8bbwe\\resources.pri? ms-resource:\/\/\/resources\/ApplicationTitleWithTagline}\r\n    Value    : News\r\n\r\n    Path     : HKEY_USERS\\.DEFAULT\\Software\\Classes\\Local Settings\\MrtCache\\C:%5CProgram Files%5CWindowsApps%5CMicrosoft.BingWeather_1.0.6.0_x64__8wekyb3d8bbwe%5Cresources.pri\\1d861e9fdbc0f2\\a37dfe62\r\n    Property : @{C:\\Program Files\\WindowsApps\\Microsoft.BingWeather_1.0.6.0_x64__8wekyb3d8bbwe\\resources.pri? ms-resource:\/\/\/resources\/ApplicationTitleWithBranding}\r\n    Value    : MSN W...\r\n\r\nPARAMETER: -RootKey \"HKEY_LOCAL_MACHINE\"\r\n    Enter the root registry key where your search will begin.\r\n\r\nPARAMETER: -SearchPath \"SOFTWARE\\ReplaceMe\"\r\n    Specify the subpath within the selected root key where the registry search should start. Exclude the root key from this path.\r\n\r\nPARAMETER: -Search \"ReplaceMe\"\r\n    Enter the text that must be present in the registry path, property, or value for it to be considered a match in the search results.\r\n\r\nPARAMETER: -Depth \"3\"\r\n    Set the maximum number of levels deep to search within the registry from the specified path. Increasing this value can significantly impact script performance due to deeper searches.\r\n\r\nPARAMETER: -CustomField \"ReplaceMeWithAnyMultilineCustomField\"\r\n    Specifies the name of an optional multiline custom field where results can be sent. Leave blank if not applicable.\r\n\r\nPARAMETER: -Path\r\n    If selected, the search will include registry key paths that contain the specified 'Search For' text as part of the search results.\r\n\r\nPARAMETER: -Property\r\n    If selected, the search will include registry key properties (names) that contain the specified 'Search For' text as part of the search results.\r\n\r\nPARAMETER: -Value\r\n    If selected, the search will include registry key values that contain the specified 'Search For' text as part of the search results.\r\n\r\n.NOTES\r\n    Minimum OS Architecture Supported: Windows 10, Windows Server 2016\r\n    Release Notes: Initial Release\r\nBy using this script, you indicate your acceptance of the following legal terms as well as our Terms of Use at https:\/\/www.ninjaone.com\/terms-of-use.\r\n    Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms. \r\n    Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party. \r\n    Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library or website belonging to or under the control of any other software provider. \r\n    Warranty Disclaimer: The script is provided \u201cas is\u201d and \u201cas available\u201d, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations. \r\n    Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks. \r\n    Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script. \r\n    EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).\r\n#&gt;\r\n\r\n[CmdletBinding()]\r\nparam (\r\n    [Parameter()]\r\n    [String]$RootKey = \"HKEY_LOCAL_MACHINE\",\r\n    [Parameter()]\r\n    [String]$SearchPath,\r\n    [Parameter()]\r\n    [String]$Search,\r\n    [Parameter()]\r\n    [int]$Depth = 4,\r\n    [Parameter()]\r\n    [String]$CustomField,\r\n    [Parameter()]\r\n    [Switch]$Path = [System.Convert]::ToBoolean($env:searchForMatchingKeyPaths),\r\n    [Parameter()]\r\n    [Switch]$Property = [System.Convert]::ToBoolean($env:searchForMatchingKeyProperties),\r\n    [Parameter()]\r\n    [Switch]$Value = [System.Convert]::ToBoolean($env:searchForMatchingKeyValues)\r\n)\r\n\r\nbegin {\r\n    if ($env:rootKeyToSearch -and $env:rootKeyToSearch -notlike \"null\") { $RootKey = $env:rootKeyToSearch }\r\n    if ($env:searchPath -and $env:searchPath -notlike \"null\") { $SearchPath = $env:searchPath }\r\n    if ($env:searchFor -and $env:searchFor -notlike \"null\") { $Search = $env:searchFor }\r\n    if ($env:searchDepth -and $env:searchDepth -notlike \"null\") { $Depth = $env:searchDepth }\r\n    if ($env:customFieldName -and $env:customFieldName -notlike \"null\") { $CustomField = $env:customFieldName }\r\n\r\n    # Error out if we're not told to match the search string with anything.\r\n    if (-not $Path -and -not $Property -and -not $Value) {\r\n        Write-Host \"[Error] You must select the option to either match based on the key path, the property name, or the value.\"\r\n        exit 1\r\n    }\r\n\r\n    # If no search string is given error out.\r\n    if ( -not $Search) {\r\n        Write-Host \"[Error] You must specify something to search for.\"\r\n        exit 1\r\n    }\r\n\r\n    # If we're not given a search path error out.\r\n    if ( -not $SearchPath) {\r\n        Write-Host \"[Error] You must specify a path to search, e.g., 'SOFTWARE\\Microsoft'.\"\r\n        exit 1\r\n    }\r\n\r\n    # If no root key is given error out.\r\n    if ( -not $RootKey) {\r\n        Write-Host \"[Error] You must specify a root key to search in.\"\r\n        exit 1\r\n    }\r\n\r\n    # Valid root keys for the search.\r\n    $ValidRootKeys = \"HKEY_LOCAL_MACHINE\", \"HKEY_CLASSES_ROOT\", \"HKEY_USERS\", \"HKEY_CURRENT_CONFIG\", \"HKEY_CURRENT_USER\"\r\n    if ($ValidRootKeys -notcontains $RootKey) {\r\n        Write-Host \"[Error] You must specify a valid root key! Valid root keys are 'HKEY_LOCAL_MACHINE', 'HKEY_CLASSES_ROOT', 'HKEY_USERS', 'HKEY_CURRENT_CONFIG', and 'HKEY_CURRENT_USER'.\"\r\n        exit 1\r\n    }\r\n\r\n    # Remove accidental backslashes.\r\n    if ($SearchPath -match \"^\\\\\") {\r\n        $SearchPath = $SearchPath -replace \"^\\\\\"\r\n        Write-Warning \"An extra backslash was detected; changing the search path to $SearchPath.\"\r\n    }\r\n\r\n    # If the search path is not valid error out.\r\n    if (-not (Test-Path \"Registry::$RootKey\\$SearchPath\")) {\r\n        Write-Host \"[Error] Search path $RootKey\\$SearchPath does not exist! Please specify an existing registry path to start the search from!\"\r\n        exit 1\r\n    }\r\n\r\n    # Depth must be greater than 0.\r\n    if ( -not $Depth -or $Depth -lt 1) {\r\n        Write-Host \"[Error] Depth must be greater than 0.\"\r\n        exit 1\r\n    }\r\n\r\n    # If depth is 5 or higher, output a warning.\r\n    if ($Depth -ge 5) {\r\n        Write-Warning \"Executing deep registry searches may significantly extend script runtime.\"\r\n    }\r\n\r\n    # If HKEY_USERS is used we'll need a list of User Profiles and where to mount the corresponding registry hives.\r\n    function Get-UserHives {\r\n        param (\r\n            [Parameter()]\r\n            [ValidateSet('AzureAD', 'DomainAndLocal', 'All')]\r\n            [String]$Type = \"All\",\r\n            [Parameter()]\r\n            [String[]]$ExcludedUsers,\r\n            [Parameter()]\r\n            [switch]$IncludeDefault\r\n        )\r\n    \r\n        # User account SID's follow a particular pattern depending on if they're Azure AD, a Domain account, or a local \"workgroup\" account.\r\n        $Patterns = switch ($Type) {\r\n            \"AzureAD\" { \"S-1-12-1-(\\d+-?){4}$\" }\r\n            \"DomainAndLocal\" { \"S-1-5-21-(\\d+-?){4}$\" }\r\n            \"All\" { \"S-1-12-1-(\\d+-?){4}$\" ; \"S-1-5-21-(\\d+-?){4}$\" } \r\n        }\r\n    \r\n        # We'll need the NTUSER.DAT file to load each user's registry hive. So we grab it if their account SID matches the above pattern. \r\n        $UserProfiles = Foreach ($Pattern in $Patterns) { \r\n            Get-ItemProperty \"HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\*\" |\r\n                Where-Object { $_.PSChildName -match $Pattern } | \r\n                Select-Object @{Name = \"SID\"; Expression = { $_.PSChildName } },\r\n                @{Name = \"UserName\"; Expression = { \"$($_.ProfileImagePath | Split-Path -Leaf)\" } }, \r\n                @{Name = \"UserHive\"; Expression = { \"$($_.ProfileImagePath)\\NTuser.dat\" } }, \r\n                @{Name = \"Path\"; Expression = { $_.ProfileImagePath } }\r\n        }\r\n    \r\n        # There are some situations where grabbing the .Default user's info is needed.\r\n        switch ($IncludeDefault) {\r\n            $True {\r\n                $DefaultProfile = \"\" | Select-Object UserName, SID, UserHive, Path\r\n                $DefaultProfile.UserName = \"Default\"\r\n                $DefaultProfile.SID = \"DefaultProfile\"\r\n                $DefaultProfile.Userhive = \"$env:SystemDrive\\Users\\Default\\NTUSER.DAT\"\r\n                $DefaultProfile.Path = \"C:\\Users\\Default\"\r\n    \r\n                $DefaultProfile | Where-Object { $ExcludedUsers -notcontains $_.UserName }\r\n            }\r\n        }\r\n    \r\n        $UserProfiles | Where-Object { $ExcludedUsers -notcontains $_.UserName }\r\n    }\r\n\r\n    function Test-IsElevated {\r\n        $id = [System.Security.Principal.WindowsIdentity]::GetCurrent()\r\n        $p = New-Object System.Security.Principal.WindowsPrincipal($id)\r\n        $p.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)\r\n    }\r\n\r\n    # This function makes it easier to set Custom Fields.\r\n    function Set-NinjaProperty {\r\n        [CmdletBinding()]\r\n        Param(\r\n            [Parameter(Mandatory = $True)]\r\n            [String]$Name,\r\n            [Parameter()]\r\n            [String]$Type,\r\n            [Parameter(Mandatory = $True, ValueFromPipeline = $True)]\r\n            $Value,\r\n            [Parameter()]\r\n            [String]$DocumentName\r\n        )\r\n    \r\n        $Characters = $Value | Measure-Object -Character | Select-Object -ExpandProperty Characters\r\n        if ($Characters -ge 10000) {\r\n            throw [System.ArgumentOutOfRangeException]::New(\"Character limit exceeded, value is greater than 10,000 characters.\")\r\n        }\r\n        \r\n        # If we're requested to set the field value for a Ninja document we'll specify it here.\r\n        $DocumentationParams = @{}\r\n        if ($DocumentName) { $DocumentationParams[\"DocumentName\"] = $DocumentName }\r\n        \r\n        # This is a list of valid fields that can be set. If no type is given, it will be assumed that the input doesn't need to be changed.\r\n        $ValidFields = \"Attachment\", \"Checkbox\", \"Date\", \"Date or Date Time\", \"Decimal\", \"Dropdown\", \"Email\", \"Integer\", \"IP Address\", \"MultiLine\", \"MultiSelect\", \"Phone\", \"Secure\", \"Text\", \"Time\", \"URL\", \"WYSIWYG\"\r\n        if ($Type -and $ValidFields -notcontains $Type) { Write-Warning \"$Type is an invalid type! Please check here for valid types. https:\/\/ninjarmm.zendesk.com\/hc\/en-us\/articles\/16973443979789-Command-Line-Interface-CLI-Supported-Fields-and-Functionality\" }\r\n        \r\n        # The field below requires additional information to be set\r\n        $NeedsOptions = \"Dropdown\"\r\n        if ($DocumentName) {\r\n            if ($NeedsOptions -contains $Type) {\r\n                # We'll redirect the error output to the success stream to make it easier to error out if nothing was found or something else went wrong.\r\n                $NinjaPropertyOptions = Ninja-Property-Docs-Options -AttributeName $Name @DocumentationParams 2&gt;&amp;1\r\n            }\r\n        }\r\n        else {\r\n            if ($NeedsOptions -contains $Type) {\r\n                $NinjaPropertyOptions = Ninja-Property-Options -Name $Name 2&gt;&amp;1\r\n            }\r\n        }\r\n        \r\n        # If an error is received it will have an exception property, the function will exit with that error information.\r\n        if ($NinjaPropertyOptions.Exception) { throw $NinjaPropertyOptions }\r\n        \r\n        # The below type's require values not typically given in order to be set. The below code will convert whatever we're given into a format ninjarmm-cli supports.\r\n        switch ($Type) {\r\n            \"Checkbox\" {\r\n                # While it's highly likely we were given a value like \"True\" or a boolean datatype it's better to be safe than sorry.\r\n                $NinjaValue = [System.Convert]::ToBoolean($Value)\r\n            }\r\n            \"Date or Date Time\" {\r\n                # Ninjarmm-cli expects the  Date-Time to be in Unix Epoch time so we'll convert it here.\r\n                $Date = (Get-Date $Value).ToUniversalTime()\r\n                $TimeSpan = New-TimeSpan (Get-Date \"1970-01-01 00:00:00\") $Date\r\n                $NinjaValue = $TimeSpan.TotalSeconds\r\n            }\r\n            \"Dropdown\" {\r\n                # Ninjarmm-cli is expecting the guid of the option we're trying to select. So we'll match up the value we were given with a guid.\r\n                $Options = $NinjaPropertyOptions -replace '=', ',' | ConvertFrom-Csv -Header \"GUID\", \"Name\"\r\n                $Selection = $Options | Where-Object { $_.Name -eq $Value } | Select-Object -ExpandProperty GUID\r\n        \r\n                if (-not $Selection) {\r\n                    throw [System.ArgumentOutOfRangeException]::New(\"Value is not present in dropdown\")\r\n                }\r\n        \r\n                $NinjaValue = $Selection\r\n            }\r\n            default {\r\n                # All the other types shouldn't require additional work on the input.\r\n                $NinjaValue = $Value\r\n            }\r\n        }\r\n        \r\n        # We'll need to set the field differently depending on if its a field in a Ninja Document or not.\r\n        if ($DocumentName) {\r\n            $CustomField = Ninja-Property-Docs-Set -AttributeName $Name -AttributeValue $NinjaValue @DocumentationParams 2&gt;&amp;1\r\n        }\r\n        else {\r\n            $CustomField = Ninja-Property-Set -Name $Name -Value $NinjaValue 2&gt;&amp;1\r\n        }\r\n        \r\n        if ($CustomField.Exception) {\r\n            throw $CustomField\r\n        }\r\n    }\r\n\r\n    $ExitCode = 0\r\n}\r\nprocess {\r\n    # Test for local administrator rights.\r\n    if (-not (Test-IsElevated)) {\r\n        Write-Host -Object \"[Error] Access Denied. Please run with Administrator privileges.\"\r\n        exit 1\r\n    }\r\n\r\n    # Load unloaded profiles if asked to search in HKEY_USERS.\r\n    if ($RootKey -eq \"HKEY_USERS\") {\r\n        $UserProfiles = Get-UserHives -Type \"All\"\r\n        $ProfileWasLoaded = New-Object System.Collections.Generic.List[string]\r\n\r\n        # Loop through each profile on the machine.\r\n        Foreach ($UserProfile in $UserProfiles) {\r\n            # Load user's NTUSER.DAT if it's not already loaded.\r\n            If ((Test-Path Registry::HKEY_USERS\\$($UserProfile.SID)) -eq $false) {\r\n                Start-Process -FilePath \"cmd.exe\" -ArgumentList \"\/C reg.exe LOAD HKU\\$($UserProfile.SID) `\"$($UserProfile.UserHive)`\"\" -Wait -WindowStyle Hidden\r\n                $ProfileWasLoaded.Add(\"$($UserProfile.SID)\")\r\n            }\r\n        }\r\n    }\r\n\r\n    # Retrieve all the registry keys with the given parameters.\r\n    $RegistryKeys = Get-ChildItem -Path \"Registry::$RootKey\\$SearchPath\" -Depth $Depth -Recurse -ErrorAction SilentlyContinue -ErrorVariable RegistryErrors\r\n\r\n    if ($RootKey -eq \"HKEY_USERS\") {\r\n        # Unload all hives that were loaded for this script.\r\n        ForEach ($UserHive in $ProfileWasLoaded) {\r\n            If ($ProfileWasLoaded -eq $false) {\r\n                [gc]::Collect()\r\n                Start-Sleep 1\r\n                Start-Process -FilePath \"cmd.exe\" -ArgumentList \"\/C reg.exe UNLOAD HKU\\$($UserHive)\" -Wait -WindowStyle Hidden | Out-Null\r\n            }\r\n        }\r\n    }\r\n\r\n    # Initialize generic lists.\r\n    $AllKeys = New-Object System.Collections.Generic.List[object]\r\n    $MatchingKeys = New-Object System.Collections.Generic.List[object]\r\n    $CustomFieldValue = New-Object System.Collections.Generic.List[string]\r\n\r\n    # For each registry key, retrieve all properties and values if available.\r\n    $RegistryKeys | ForEach-Object {\r\n        $RegistryPath = $_.PSPATH -replace \"Microsoft.PowerShell.Core\\\\Registry::\"\r\n        try {\r\n            $ErrorActionPreference = \"Stop\"\r\n            $Properties = New-Object System.Collections.Generic.List[string]\r\n            $_.GetValueNames() | ForEach-Object { $Properties.Add($_) }\r\n            $Properties.Add(\"(default)\")\r\n        }\r\n        catch {\r\n            $Properties = $Null\r\n        }\r\n        $ErrorActionPreference = \"Continue\"\r\n\r\n        if (-not $Properties) {\r\n            $AllKeys.Add(\r\n                [PSCustomObject]@{\r\n                    Path     = $RegistryPath\r\n                    Property = \"N\/A\"\r\n                    Value    = \"N\/A\"\r\n                }\r\n            )\r\n            return\r\n        }\r\n\r\n        foreach ($PropertyName in $Properties) {\r\n            $ErrorActionPreference = \"SilentlyContinue\"\r\n            $RegValue = ($_ | Get-ItemProperty -ErrorVariable RegistryErrors).$PropertyName\r\n            $ErrorActionPreference = \"Continue\"\r\n            $AllKeys.Add(\r\n                [PSCustomObject]@{\r\n                    Path     = $RegistryPath\r\n                    Property = $PropertyName\r\n                    Value    = $RegValue\r\n                }\r\n            )\r\n        }\r\n    }\r\n\r\n    $MatchingValues = $False\r\n    $MatchingProperties = $False\r\n    $MatchingPaths = $False\r\n\r\n    # Match the registry keys based on the key path, property, or value. Add the results to the MatchingKeys generic list.\r\n    if ($Value) {\r\n        $AllKeys | Where-Object { $_.Value -match [regex]::Escape($Search) } | ForEach-Object {\r\n            $MatchingValues = $True \r\n            $MatchingKeys.Add($_) \r\n        }\r\n    }\r\n\r\n    if ($Property) {\r\n        $AllKeys | Where-Object { $_.Property -match [regex]::Escape($Search) } | ForEach-Object {\r\n            $MatchingProperties = $True \r\n            $MatchingKeys.Add($_) \r\n        }\r\n    }\r\n\r\n    if ($Path) {\r\n        $AllKeys | Where-Object { $_.Path -match $([regex]::Escape($Search)) } | ForEach-Object {\r\n            $MatchingPaths = $True \r\n            $MatchingKeys.Add($_) \r\n        }\r\n    }\r\n\r\n    if (-not $MatchingPaths -and -not $MatchingProperties -and -not $MatchingValues) {\r\n        $CustomFieldValue.Add(\"No matching registry keys found!\")\r\n        Write-Host \"No matching registry keys found!\"\r\n    }\r\n\r\n    # If we have any matches, output to Write-Warning.\r\n    if ($MatchingPaths) {\r\n        Write-Warning -Message \"Matching registry path names found!\"\r\n        $CustomFieldValue.Add(\"WARNING: Matching registry path names found!\")\r\n    }\r\n\r\n    if ($MatchingProperties) {\r\n        Write-Warning -Message \"Matching registry properties found!\"\r\n        $CustomFieldValue.Add(\"WARNING: Matching registry properties found!\")\r\n    }\r\n\r\n    if ($MatchingValues) {\r\n        Write-Warning -Message \"Matching registry key values found!\"\r\n        $CustomFieldValue.Add(\"WARNING: Matching registry key values found!\")\r\n    }\r\n    \r\n    if ($MatchingKeys) {\r\n        $KeysToReport = $MatchingKeys | Format-List Path, Property, Value | Out-String\r\n        $CustomFieldValue.Add($KeysToReport)\r\n    }\r\n\r\n    # For each error, output them at the bottom. Most of these errors are not going to be relevant.\r\n    $RegistryErrors | ForEach-Object {\r\n        $CustomFieldValue.Add(\"[Error] $($_.TargetObject)\")\r\n        $CustomFieldValue.Add(\"[Error] $($_.Exception.Message)\")\r\n    }\r\n\r\n    # Save the output to a custom field if a field name is provided.\r\n    if ($CustomField) {\r\n        try {\r\n            Write-Host \"Attempting to set Custom Field '$CustomField'.\"\r\n            Set-NinjaProperty -Name $CustomField -Value (($CustomFieldValue | Out-String) -replace \"`n\")\r\n            Write-Host \"Successfully set Custom Field '$CustomField'!\"\r\n        }\r\n        catch {\r\n            if ($_.Exception.Message) {\r\n                Write-Host \"[Error] $($_.Exception.Message)\"\r\n            }\r\n        \r\n            if ($_.Message) {\r\n                Write-Host \"[Error] $($_.Message)\"\r\n            }\r\n            $ExitCode = 1\r\n        }\r\n    }\r\n\r\n    # Activity Log output\r\n    if($MatchingKeys){\r\n        $KeysToReport | Write-Host\r\n    }\r\n\r\n    $RegistryErrors | ForEach-Object {\r\n        Write-Host \"[Error] $($_.TargetObject)\"\r\n        Write-Host \"[Error] $($_.Exception.Message)\"\r\n    }\r\n\r\n    exit $ExitCode\r\n}\r\nend {\r\n    \r\n    \r\n    \r\n}<\/pre>\n<p>&nbsp;<\/p>\n\n<div class=\"blog-cta-new blog-cta-style-1\"><div class=\"cta-left\"><h2><\/h2><p><\/p><\/div><div class=\"cta-right\"><a class=\"button\" href=\"\"><\/a><\/div><\/div>\n<h2>An\u00e1lisis detallado<\/h2>\n<p>El script para buscar claves de registro comienza definiendo par\u00e1metros que permiten al usuario especificar la clave ra\u00edz, la ruta de b\u00fasqueda, el texto de b\u00fasqueda, la profundidad de la b\u00fasqueda y si incluir rutas, propiedades o valores en la b\u00fasqueda. Tambi\u00e9n maneja variables de entorno que pueden predefinir estos par\u00e1metros, lo que aumenta su flexibilidad.<\/p>\n<h2>Validaciones y preparativos<\/h2>\n<p>Antes de proceder a la b\u00fasqueda, el script para buscar claves de registro realiza varias comprobaciones:<\/p>\n<ol>\n<li data-leveltext=\"%1.\" data-font=\"Aptos\" data-listid=\"1\" data-list-defn-props=\"{&quot;335552541&quot;:0,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769242&quot;:[65533,0],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;%1.&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"1\" data-aria-level=\"1\"><strong>Validaci\u00f3n de la clave ra\u00edz<\/strong>: asegura que la clave ra\u00edz proporcionada es v\u00e1lida.<\/li>\n<li data-leveltext=\"%1.\" data-font=\"Aptos\" data-listid=\"1\" data-list-defn-props=\"{&quot;335552541&quot;:0,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769242&quot;:[65533,0],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;%1.&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"1\" data-aria-level=\"1\"><strong>Correcci\u00f3n de la ruta<\/strong>: elimina cualquier barra invertida inicial accidental de la ruta de b\u00fasqueda.<\/li>\n<li data-leveltext=\"%1.\" data-font=\"Aptos\" data-listid=\"1\" data-list-defn-props=\"{&quot;335552541&quot;:0,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769242&quot;:[65533,0],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;%1.&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"1\" data-aria-level=\"1\"><strong>Comprobaci\u00f3n de existencia<\/strong>: verifica que la ruta de b\u00fasqueda especificada existe dentro de la clave ra\u00edz.<\/li>\n<li data-leveltext=\"%1.\" data-font=\"Aptos\" data-listid=\"1\" data-list-defn-props=\"{&quot;335552541&quot;:0,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769242&quot;:[65533,0],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;%1.&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"1\" data-aria-level=\"1\"><strong>Comprobaci\u00f3n de profundidad<\/strong>: asegura que el valor de profundidad es mayor que cero.<\/li>\n<\/ol>\n<h2>Gesti\u00f3n de colmenas de usuarios<\/h2>\n<p>Si la b\u00fasqueda afecta a la clave ra\u00edz HKEY_USERS, el script para buscar claves de registro carga din\u00e1micamente los archivos comprimidos del registro de usuarios. Esto es crucial para buscar configuraciones espec\u00edficas del usuario que no se cargan por defecto. Tambi\u00e9n garantiza que las colmenas cargadas se descarguen despu\u00e9s de la b\u00fasqueda para mantener la integridad del sistema.<\/p>\n<h2>B\u00fasqueda en el registro<\/h2>\n<p>La funcionalidad principal implica la b\u00fasqueda recursiva a trav\u00e9s de la ruta de registro especificada hasta la profundidad definida. El script para buscar claves de registro recopila todas las claves del registro y las eval\u00faa en funci\u00f3n de los criterios de b\u00fasqueda (ruta, propiedad o valor). Las claves coincidentes se compilan en una lista y se generan las advertencias pertinentes si se encuentran coincidencias.<\/p>\n<h2>Tratamiento de errores e informes<\/h2>\n<p>A lo largo del proceso, el script para buscar claves de registro captura los errores y los registra para su revisi\u00f3n. Esto es especialmente \u00fatil para identificar y resolver los problemas encontrados durante la b\u00fasqueda. Los resultados, incluidos los errores y las coincidencias, pueden enviarse a un campo personalizado si as\u00ed se especifica, lo que facilita su integraci\u00f3n con herramientas de documentaci\u00f3n o supervisi\u00f3n.<\/p>\n<h2>Ejemplo de salida<\/h2>\n<p>A continuaci\u00f3n se muestra un ejemplo de c\u00f3mo el script para buscar claves de registro podr\u00eda mostrar los resultados:<\/p>\n<p>ADVERTENCIA: \u00a1Se han encontrado nombres de rutas de registro coincidentes! ADVERTENCIA: \u00a1Se han encontrado propiedades de registro coincidentes! ADVERTENCIA: \u00a1Se han encontrado valores de clave de registro coincidentes!<\/p>\n<p>Ruta: HKEY_USERS.DEFAULTSoftwareAppDataLowSoftwareMicrosoft Property : Valor N\/A: N\/A<\/p>\n<p>Ruta: HKEY_USERS.DEFAULTSoftwareClassesLocal SettingsMrtCache&#8230; Propiedad: @{&#8230;} Valor : Microsoft Clipchamp<\/p>\n<h2>Posibles casos de uso<\/h2>\n<p>Imag\u00ednate a un profesional de TI encargado de verificar que todos los usuarios de una organizaci\u00f3n tienen correctamente configurada una aplicaci\u00f3n espec\u00edfica. Comprobar manualmente la configuraci\u00f3n del registro de cada usuario ser\u00eda poco pr\u00e1ctico. Utilizando este script para buscar claves de registro, puede automatizar la b\u00fasqueda en todos los perfiles de usuario, identificando r\u00e1pidamente cualquier discrepancia y garantizando el cumplimiento de las pol\u00edticas de la empresa.<\/p>\n<h3>Auditor\u00eda de instalaciones de software<\/h3>\n<p>Otro escenario podr\u00eda implicar la auditor\u00eda de instalaciones de software en varias m\u00e1quinas. El script puede buscar entradas del registro relacionadas con software espec\u00edfico, proporcionando un informe completo sobre d\u00f3nde y c\u00f3mo est\u00e1 configurado el software.<\/p>\n<h3>Comparaciones<\/h3>\n<p>En comparaci\u00f3n con los m\u00e9todos manuales o el uso de herramientas b\u00e1sicas de b\u00fasqueda en el registro, este script para buscar claves de registro ofrece varias ventajas:<\/p>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"1\" data-aria-level=\"1\"><strong>Eficacia<\/strong>: automatiza el proceso de b\u00fasqueda, con el consiguiente ahorro de tiempo.<\/li>\n<\/ul>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"2\" data-aria-level=\"1\"><strong>Precisi\u00f3n<\/strong>: reduce el riesgo de error humano durante las b\u00fasquedas.<\/li>\n<\/ul>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"3\" data-aria-level=\"1\"><strong>Flexibilidad<\/strong>: los par\u00e1metros personalizables permiten realizar b\u00fasquedas espec\u00edficas.<\/li>\n<\/ul>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"4\" data-aria-level=\"1\"><strong>Escalabilidad<\/strong>: puede gestionar b\u00fasquedas en numerosos perfiles de usuario y claves profundamente anidadas.<\/li>\n<\/ul>\n<p>Otros m\u00e9todos, como el uso del Editor del Registro de Windows integrado o de herramientas de terceros, suelen carecer de la flexibilidad y la capacidad de automatizaci\u00f3n del script, por lo que resultan menos adecuados para tareas repetitivas o a gran escala.<\/p>\n<h2>FAQ<\/h2>\n<h3>P: \u00bfEste script puede modificar las claves del registro?<\/h3>\n<p>R: No, el script para buscar claves de registro est\u00e1 dise\u00f1ado \u00fanicamente para realizar b\u00fasquedas e informes. No realiza ning\u00fan cambio en el registro.<\/p>\n<h3>P: \u00bfEs seguro ejecutar este script en sistemas de producci\u00f3n?<\/h3>\n<p>R: S\u00ed, el script para buscar claves de registro s\u00f3lo lee los datos del registro y no modifica la configuraci\u00f3n del sistema, por lo que es seguro para su uso en sistemas de producci\u00f3n.<\/p>\n<h3>P: \u00bfC\u00f3mo puedo especificar varios criterios de b\u00fasqueda?<\/h3>\n<p>R: Puedes personalizar los par\u00e1metros del script para buscar claves de registro para incluir m\u00faltiples criterios, como rutas, propiedades y valores, para una b\u00fasqueda exhaustiva.<\/p>\n<h3>P: \u00bfQu\u00e9 debo hacer si el script tarda demasiado en ejecutarse?<\/h3>\n<p>R: Considera reducir la profundidad de b\u00fasqueda o estrechar la ruta de b\u00fasqueda para mejorar el rendimiento. Ten en cuenta que las b\u00fasquedas profundas pueden afectar significativamente al tiempo de ejecuci\u00f3n.<\/p>\n<h2>Implicaciones<\/h2>\n<p>La capacidad de buscar eficazmente en el registro tiene implicaciones m\u00e1s amplias para la seguridad inform\u00e1tica y la gesti\u00f3n de sistemas. Al identificar y auditar r\u00e1pidamente la configuraci\u00f3n del registro, los profesionales de TI pueden garantizar el cumplimiento de las pol\u00edticas de seguridad, detectar cambios no autorizados y mantener la integridad de las configuraciones del sistema.<\/p>\n<h2>Recomendaciones<\/h2>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"5\" data-aria-level=\"1\"><strong>Ejecuta con privilegios de administrador<\/strong>: aseg\u00farate de que el script se ejecuta con derechos administrativos para acceder a todas las claves de registro necesarias.<\/li>\n<\/ul>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"6\" data-aria-level=\"1\"><strong>Haz pruebas en un entorno controlado<\/strong>: antes de desplegar el script en un entorno de producci\u00f3n, pru\u00e9balo en un entorno controlado para verificar su comportamiento y rendimiento.<\/li>\n<\/ul>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"7\" data-aria-level=\"1\"><strong>Realiza auditor\u00edas de forma peri\u00f3dica<\/strong>: utiliza el script como parte de las auditor\u00edas regulares del sistema para mantener un conocimiento actualizado de las configuraciones del registro.<\/li>\n<\/ul>\n<h2>Reflexiones finales<\/h2>\n<p>Los scripts de PowerShell, como el que se describe aqu\u00ed para buscar claves de registro, desempe\u00f1an un papel fundamental en la gesti\u00f3n moderna de TI. Ofrecen una forma potente, flexible y eficaz de gestionar tareas complejas, como la b\u00fasqueda en el Registro de Windows. Para los MSP y los profesionales de TI, el aprovechamiento de estas herramientas puede mejorar significativamente la eficacia y la precisi\u00f3n operativas.<\/p>\n<p><a href=\"https:\/\/www.ninjaone.com\/es\/\" target=\"_blank\" rel=\"noopener\">NinjaOne<\/a> proporciona una plataforma completa que puede integrar este tipo de scripts, permitiendo una gesti\u00f3n y automatizaci\u00f3n de las tareas de TI sin interrupciones. Al incorporar este script para buscar claves de registro al conjunto de herramientas de NinjaOne, los profesionales de TI pueden agilizar a\u00fan m\u00e1s sus flujos de trabajo y garantizar una s\u00f3lida gesti\u00f3n y <a href=\"https:\/\/www.ninjaone.com\/es\/?page_id=310645\" target=\"_blank\" rel=\"noopener\">seguridad<\/a> del sistema.<\/p>\n","protected":false},"author":35,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"_relevanssi_hide_post":"","_relevanssi_hide_content":"","_relevanssi_pin_for_all":"","_relevanssi_pin_keywords":"","_relevanssi_unpin_keywords":"","_relevanssi_related_keywords":"","_relevanssi_related_include_ids":"","_relevanssi_related_exclude_ids":"","_relevanssi_related_no_append":"","_relevanssi_related_not_related":"","_relevanssi_related_posts":"","_relevanssi_noindex_reason":"","_lmt_disableupdate":"","_lmt_disable":""},"operating_system":[4212],"use_cases":[4259],"class_list":["post-353768","script_hub","type-script_hub","status-publish","hentry","script_hub_category-windows"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.ninjaone.com\/es\/wp-json\/wp\/v2\/script_hub\/353768","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.ninjaone.com\/es\/wp-json\/wp\/v2\/script_hub"}],"about":[{"href":"https:\/\/www.ninjaone.com\/es\/wp-json\/wp\/v2\/types\/script_hub"}],"author":[{"embeddable":true,"href":"https:\/\/www.ninjaone.com\/es\/wp-json\/wp\/v2\/users\/35"}],"replies":[{"embeddable":true,"href":"https:\/\/www.ninjaone.com\/es\/wp-json\/wp\/v2\/comments?post=353768"}],"wp:attachment":[{"href":"https:\/\/www.ninjaone.com\/es\/wp-json\/wp\/v2\/media?parent=353768"}],"wp:term":[{"taxonomy":"script_hub_category","embeddable":true,"href":"https:\/\/www.ninjaone.com\/es\/wp-json\/wp\/v2\/operating_system?post=353768"},{"taxonomy":"use_cases","embeddable":true,"href":"https:\/\/www.ninjaone.com\/es\/wp-json\/wp\/v2\/use_cases?post=353768"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}