Bookmark and Share

In this post:

 

How Can I Read the Default Value of a Registry Key?

Hey, Scripting Guy! Question

Hey, Scripting Guy! You had a great post on Monday about setting the default value of a registry key. It is half of what has been bugging me lately. The other half is how to read the default value. I want to retrieve a string, but what I get is a PSCustomObject. Moreover, I cannot figure out how to get the string out of the PSCustomObject. What gives?

-- WB

 

Hey, Scripting Guy! AnswerHello WB,

Microsoft Scripting Guy Ed Wilson here. I am glad you enjoyed the registry article that I wrote. As for reading the default value, obviously you have noticed that when you open a set of parentheses, Windows PowerShell thinks it is getting ready to call a method. Therefore, it looks for a method named default. In addition, you are unable to escape the parentheses because of the dotted notation. So you are stuck!

The pscustom object is the way that Windows PowerShell exposes the item properties from the registry. It is not a native .NET Framework class, and therefore was created by the Windows PowerShell team as part of the Registry provider. The registry properties are exposed as an instance of the PSNoteProperty class. PSNoteProperties have name and value properties associated with them.

You can therefore access the base objectthe PSNoteProperty classdirectly by using the .psbase property that is available on all Windows PowerShell objects. After you do this, you can return all the properties by querying the properties property. From there, you have an instance of the PSNoteProperty and can access its value. Unfortunately, this is exposed as a collection, and you must use the ForEach-Object cmdlet to walk through the collection. The % character is an alias for the ForEach-Object cmdlet. This is what I came up with. It is a bit ugly, and if you can find a better way of doing it, please let me know.

PS C:\> Get-ItemProperty HKCU:\Software\ScriptingGuys | %{$_.psbase.properties | % {$_.value}}

NewValue

PS C:\>

Reply from WB: Because of my fumble fingers and cross-eyes, I was not able to get your script to work for some time. It seems I was applying the default value to the wrong key and then could not understand why it could not be read. After I got that little glitch straightened out, it worked fine.

While struggling with all this, I stumbled on another script that also seems to work:

PS C:\> (Get-ItemProperty -path HKCU:\Software\ScriptingGuys -name "(default)")."(default)"

It almost looks as if you can use dot notation with a quoted property name. Weird.


 

How Can I Get Windows PowerShell for Window 7? 

Hey, Scripting Guy! Question

Hey, Scripting Guy! I am trying to install Windows PowerShell on a Windows 7 computer that was formerly Windows XP Professional. I have tried to install using "Windows6.0-KB928439-x86.msu" and then "Windows6.0-KB968930-x86.msu." In both cases, I get a message from Windows Update Standalone Installer saying, "The update is not applicable to your computer." Both installations worked on Windows Vista.

Where is the Windows 7 version of Windows PowerShell?

-- DD

 

Hey, Scripting Guy! AnswerHello DD,

There is no need to install Windows PowerShell on Windows 7. It is already installed. You can access it by clicking Start, pointing to All Programs, clicking Accessories, and then clicking Windows PowerShell, as seen in the following image.

Image of Windows PowerShell location in Windows 7


 

Getting the Get-WmiObject Cmdlet to Work

Hey, Scripting Guy! Question

Hey, Scripting Guy! I cannot seem to get past the “Access is denied” error message when I try to run the Get-WmiObject cmdlet in Windows PowerShell. I am a domain administrator, and I am running the command against my local workstation. I have tried setting the authentication level to everything from 0 to 6, but the result is the same. The error I am getting is seen here:

PS C:\Documents and Settings\kengadmin> Get-WmiObject -Class Win32_Desktop -ComputerName . -authentication -6

Get-WmiObject : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))

At line:1 char:14

+ Get-WmiObject <<<<  -Class Win32_Desktop -ComputerName localhost -authentication -6

    + CategoryInfo          : NotSpecified: (:) [Get-WmiObject], UnauthorizedAccessException

    + FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

-- KG

 

Hey, Scripting Guy! AnswerHello KG,

The best way to answer your question is to look at some examples that work, and some that do not work. This example works:

gwmi win32_desktop

 

This example also works: 

PS C:\> gwmi win32_desktop -ComputerName .

 

This example also works:

PS C:\> gwmi win32_desktop -ComputerName "." -Authentication 6

 

This example does not work:

PS C:\> Get-WmiObject -Class Win32_Desktop -ComputerName . -authentication -6

Get-WmiObject : The authentication level is unknown.

At line:1 char:14

+ Get-WmiObject <<<<  -Class Win32_Desktop -ComputerName . -authentication -6

    + CategoryInfo          : InvalidOperation: (:) [Get-WmiObject], ManagementException

    + FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

 

PS C:\>

 

I am not getting an authentication error. You must have quotation marks around the period when it is followed by an additional parameter. In addition, you do not need the dash in front of the authentication level. You should not need to specify an authentication level when connecting locally when using WMI.
 

 

What's the Best Way to Detect Registry Keys Using the WMI Provider?

Hey, Scripting Guy! Question

Hey, Scripting Guy!   In your article, Hey, Scripting Guy! How Can I Tell Whether a Value Exists in the Registry?, you have the following code:

strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion"
strValueName = "Test Value"
objRegistry.GetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue

If IsNull(strValue) Then
    Wscript.Echo "The registry key does not exist."
Else
    Wscript.Echo "The registry key exists."
End If

 

The problem occurs when the key for which I'm checkingif it existsusually has only one value, "(Default)", which is set to Null.  The key is the Control subkey of each connected device at the following location:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum.

So my question is do you guys know a better way to detect the presence or absence of registry keys using the WMI provider?

-- SG

 

Hey, Scripting Guy! AnswerHello SG,

There are lots of ways to work with the registry. We have a collection of methods that we have written about over the years. You can look through them in the Hey, Scripting Guy! archive 

SG replies: Ed, Thank you very much for your personal reply.  It is awesome to have a real human being answer an e-mail! I want to let you know that I stumbled upon a solution by accident.  I am getting consistent, desirable results by checking the status code returned by EnumValues:

If oReg.EnumValues(hexHive, strPath, arrValueNames, arrValueTypes) = 0 Then bKeyExists = True

 

I also want to let you know that I have a few startup scripts that manipulate Access databases, using the (32-bit only) Jet provider.  I recently installed 64-bit Windows 7, and of course my scripts did not work.  I beat my head against a wall for a few hours, until I realized I could just spawn the 32-bit Script Host: 

Set oSH = CreateObject("WScript.Shell")
Set oFS = CreateObject("Scripting.FileSystemObject")

 

strOldWSH = oSH.ExpandEnvironmentStrings("%SYSTEMROOT%\SysWOW64\wscript.exe")
If oFS.FileExists(strOldWSH) Then
    If Not UCase(WScript.FullName) = UCase(strOldWSH) Then
        oSH.Run """" & strOldWSH & """ """ & WScript.ScriptFullName & """", 1, False
        WScript.Echo "Running on 64-bit WSH."
        WScript.Quit
    End If
End If

 

WScript.Sleep 10000
WScript.Echo "Running on 32-bit WSH."

 

I hope this helps someone! 

Ed Wilson replies: Thank you for the tips. We’re sharing them in hopes that they are just what someone else reading this is looking for.

 

Well, this concludes another edition of Quick-Hits Friday. It also concludes another exciting week on the Script Center. Join us next week as we delve into the mysteries of…wellllllllllll, we will let that remain a mystery for now.

If you want to know exactly what we will be covering on Monday, follow us on Twitter or Facebook. If you have any questions, send e-mail to us at scripter@microsoft.com or post your questions on the Official Scripting Guys Forum. See you on Monday. Until then, have an awesome weekend.

 

Ed Wilson and Craig Liebendorfer, Scripting Guys