Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
830 views
in Technique[技术] by (71.8m points)

how to filter name/value pairs under a registry key by name and value in PowerShell?

I'm trying to get a feel for the idioms to use in PowerShell.

Given this script:

$path = 'hkcu:SoftwareMicrosoftWindowsCurrentVersionExtensions'
$key = Get-Item $path
$key

I get the output at the bottom of this question.

I'd like to get output of the properties (the name/value pairs under the $key) where I can filter on both name and value.

For instance, filter to list all the Extensions that have:

  • name like xls*
  • or value like *MSACCESS.EXE

Or an exclude filter: exclude all names like doc*

Fir the first filter, I'd want a result like this:

Name                           Value                                                                                                                                                       
----                           --------                                                                                                                                                       
xlsx                           C:PROGRA~2MICROS~1Office15EXCEL.EXE                                                                                                                 
xls                            C:PROGRA~2MICROS~1Office15EXCEL.EXE                                                                                                                 
mdb                            C:PROGRA~2MICROS~1Office15MSACCESS.EXE                                                                                                              
mda                            C:PROGRA~2MICROS~1Office15MSACCESS.EXE                                                                                                              

This is the original output of the script:

Hive: HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersion
Name                           Property                                                                                                                                                       
----                           --------                                                                                                                                                       
Extensions                     rtf  : C:PROGRA~2MICROS~1Office15WINWORD.EXE ^.rtf                                                                                                         
                               dot  : C:PROGRA~2MICROS~1Office15WINWORD.EXE ^.dot                                                                                                         
                               dotm : C:PROGRA~2MICROS~1Office15WINWORD.EXE ^.dotm                                                                                                        
                               dotx : C:PROGRA~2MICROS~1Office15WINWORD.EXE ^.dotx                                                                                                        
                               docm : C:PROGRA~2MICROS~1Office15WINWORD.EXE ^.docm                                                                                                        
                               docx : C:PROGRA~2MICROS~1Office15WINWORD.EXE ^.docx                                                                                                        
                               doc  : C:PROGRA~2MICROS~1Office15WINWORD.EXE ^.doc                                                                                                         
                               xlsx : C:PROGRA~2MICROS~1Office15EXCEL.EXE                                                                                                                 
                               xls  : C:PROGRA~2MICROS~1Office15EXCEL.EXE                                                                                                                 
                               mdb  : C:PROGRA~2MICROS~1Office15MSACCESS.EXE                                                                                                              
                               mda  : C:PROGRA~2MICROS~1Office15MSACCESS.EXE                                                                                                              

Edit

I solved part of the problem: getting a list of Name/Value pairs. It uses PSCustomObject:

$namevalues = $key.GetValueNames() | ForEach-Object { [pscustomobject]@{ Name=$_; Value=$key.GetValue($_) } }
$namevalues

(How should I wrap that code?)

Any help with the filtering would be much appreciated

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

A two part answer.

We start with the $key from the registry:

$path = 'hkcu:SoftwareMicrosoftWindowsCurrentVersionExtensions'
$key = Get-Item $path
$key
$key | Get-Member

Since $key is a Microsoft.Win32.RegistryKey, you cannot get the name value pairs out directly.

The first step is to create a list of PSCustomObjects with Name/Value pairs. The Name comes from the GetValueNames piped through a ForEach-Object. For each of those Names, we get the Value through GetValue:

$namevalues = $key.GetValueNames() | 
  ForEach-Object { 
    [PSCustomObject] @{ 
      Name = $_; 
      Value = $key.GetValue($_) 
    } 
  }
$namevalues | Format-Table

An alternative for the first step is to use the Select-Object using -ExpandProperty as explained by Scott Saad:

$namevalues = $key | Select-Object -ExpandProperty Property | 
  ForEach-Object { 
    [PSCustomObject] @{ 
      Name = $_; 
      Value = $key.GetValue($_) 
    } 
  }
$namevalues | Format-Table

The second step is to filter the $namevalues either by Name or by Value.

The Where-Object has some pretty cool Comparison operators that accept regular expressions like match, notMatch, etc.

To make the code more readable, you can wrap lines (thanks Joey!) either use the backtick (`) or take advantage of the places in the PowerShell syntax where it does accept line breaks, like after a pipe (|) or opening brace ({):

$matches = $namevalues | 
  Where-Object { 
    $_.Name -match '^xls' `
    -or $_.Value -match 'msaccess.exe$' 
  }
$matches | Format-Table

The result is as wanted:

Name    Value                                                                                         
----    -----                                                                                         
xlsx    C:PROGRA~2MICROS~1Office15EXCEL.EXE                                                       
xls     C:PROGRA~2MICROS~1Office15EXCEL.EXE                                                       
mdb     C:PROGRA~2MICROS~1Office15MSACCESS.EXE                                                    
mda     C:PROGRA~2MICROS~1Office15MSACCESS.EXE

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...