Using Powershell to grab Registry Key data to build an If Else - powershell

I am trying to use Powershell to check a particular registry key we use on servers in HKLM\SOFTWARE to identify their status as an Alpha, Beta or General server. I am not seeing an easy way to do this. I took a look at the Get-ItemProperty cmdlet, but that doesn't allow me to actually select the exact key within SOFTWARE that has the data I need to build out an If Else loop that can output the server type.
In its simplest form, I would like to use this Powershell script to read that key (to see if Alpha, Beta, General) and then depending on which, output simply Alpha, Beta or General as a text file.

Have you tried Get-Item?
$keyInfo = Get-Item -Path $Key
#Where Key is something like hklm:\Software..
#This will give you all the subkeys to that key
$keyInfo.GetSubKeyNames()
#This will give you data stored in the values of the key.
$keyInfo.GetValue($ValueName, $null, [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames)

Related

Powershell registry access multiple options

To access or make changes to registry in a windows machine by powershell, I see two ways
cd HKLM:\ (or set-location -path
HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion)
Get-childitem
or
Get-Item -path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
Get-ItemProperty , New-ItemProperty , Set-ItemProperty
When to use one over the other?
They are both necessary, because the property values aren't accessible on the Item objects (and you can't see the nested "child" container items with the ItemProperty commands).
My 2c: the registry provider was written by someone as a demo, and then shipped and now they're afraid to change it ... it's the only way to explain the whole "ItemProperty" thing.
Basically, when they mapped the registry to the PowerShell Provider semantics, instead of having "Container" and "Leaf" items, there are only containers, and each container has properties (and/or child containers).
So if you do Get-ChildItem HKCU:\SOFTWARE\Microsoft you get a response back listing the "Name" of each of the child containers (which the Registry Editory (Regedit.exe) would show as folders), and listing the values in them under the heading "Property" -- but that listing is purely in the display, and the Property field on the object you got back is actually just a string array listing the names of the properties so you know what you can do next:
If you want to actually read the values in a way that makes them accessible to your script, you need to use Get-ItemProperty
If you want to change the value, you need to use Set-ItemProperty
To create new ones, you need to use New-ItemProperty
In your example, for instance, you might see SecurityHealth:
But it's like the screenshot above, as a human, you can see the value, but your script can't read the value...
You have to use Get-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run to get an object back that actually has the SecurityHealth property with the C:\WINDOWS\System32\SecurityHealthSystray.exe value...

Powershell: Cannot read a specific Registry-Value

I am struggling to read this REG-value via Powershell 5:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\SWD\DAFWSDProvider\urn:uuid:cfe92100-67c4-11d4-a45f-0026abfabc42/uri:urn:uuid:cfe92100-67c4-11d4-a45f-0026abfabc42/01]
"Driver"="{6bdd1fc6-810f-11d0-bec7-08002be2092f}\\0000"
Even the autocomplete-function in Powershell showing me the REG-path to that key is not working properly.
Why is it failing? How can I get this value?
This is the code which is surprisingly NOT working as expected:
$sub = 'urn:uuid:cfe92100-67c4-11d4-a45f-0026abfabc42/uri:urn:uuid:cfe92100-67c4-11d4-a45f-0026abfabc42/01'
get-Item -literalPath "HKLM:\SYSTEM\CurrentControlSet\Enum\SWD\DAFWSDProvider\$sub"
Here a screenshot of the subkey that I cannot read:
I could now drill it down to this situation:
subkey 'urn:uuid:cfe92100-67c4-11d4-a45f-0026abfabc42' -> OK
subkey 'uuid:cfe92100-67c4-11d4-a45f-0026abfabc42/u' -> OK
subkey 'urn:uuid:cfe92100-67c4-11d4-a45f-0026abfabc42/u' -> fail!
subkey 'urn:uuid:cfe92100-67c4-11d4-a45f-0026abfabc42/u' under HKLM:\Software -> OK
Using Sysinternals Process Explorer, I've discovered what happens.
PowerShell replaces the forward slashes in the path unconditionally with backslashes, even when you use -LiteralPath.
That's clearly a bug.
To work around it, you can use the PSPath of the registry key, apparently PowerShell leaves those alone. For the local registry, the PSPath always starts like this:
Microsoft.PowerShell.Core\Registry::
and after that goes on with the regular key name as it would appear in RegEdit.
$path = "Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\SWD\DAFWSDProvider\urn:uuid:e3248000-80ce-11db-8000-30055c83410f/uri:e3248000-80ce-11db-8000-30055c83410f/PrinterService"
Get-Item $path
PSPaths are an integral part of anything that Powershell treats as one of its drives. You can select them, or access the .PSPath property:
$path = "Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\SWD\DAFWSDProvider"
Get-ChildItem $path | Select -ExpandProperty PSPath
(Get-Item C:\).PSPath
At the end it turns out, that I had to use a different Syntax for the REG-Path to make the call work - very strange!
See this code:
$prefix1 = "Registry::HKEY_LOCAL_MACHINE"
$prefix2 = "HKLM:"
$subDir = "urn:uuid:cfe92100-67c4-11d4-a45f-0026abfabc42/uri:urn:uuid:cfe92100-67c4-11d4-a45f-0026abfabc42/01"
get-item "$prefix1\SYSTEM\CurrentControlSet\Enum\SWD\DAFWSDProvider\$subDir"
get-item "$prefix2\SYSTEM\CurrentControlSet\Enum\SWD\DAFWSDProvider\$subDir"
The first "get-item" call using prefix1 is working fine while the second one is not returning anything back.
Lession learned: Better use the longer REG-Prefix like in the original PSPATH to avoid any unexpected side-effects.
From Microsoft's PowerShell documentation, you can decide if you would like to view the entries as a list or to retrieve a single registry key.
https://learn.microsoft.com/en-us/powershell/scripting/samples/working-with-registry-entries?view=powershell-7.1

Using system variable within string to get file version in Powershell

I am trying to get something like this to work but cannot figure it out.
(Get-Item env:userprofile\AppData\Local\Microsoft\OneDrive\OneDrive.exe).VersionInfo.FileVersion
I am getting an error that it does not exist, though I know it does.
If I run the same thing with a known logged in user like below,
(Get-Item c:\users\jonesb\AppData\Local\Microsoft\OneDrive\OneDrive.exe).VersionInfo.FileVersion
I get the versioning I am looking for. I will be running this script on thousands of machines and I don't know who will be logged in to each machine. Please advise.
env:userprofile expands to env:\userprofile. This is a PSDrive, which you can access with Cmdlets like Get-Item, but it does not expand in strings. What you need to do is to use the variable $env:userprofile.
(Get-Item $env:userprofile\AppData\Local\Microsoft\OneDrive\OneDrive.exe).VersionInfo.FileVersion

Is it possible to get performance counter description using Powershell command get-counter?

On Windows, we can easily get the description of a performance counter by using the perfmon utility. Take a look at the description section in below snapshot.
Is it possible to get this info from Powershell's get-counter cmdlet?
It appears that information is stored in the registry at (for English):
HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009 in the multi-string key Help
So since PowerShell can use the Registry as a Provider, yes you can get this information technically although it's a bit ugly:
(Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009").Help
That will pull all the text from the help entry, which you can then filter through with pipes/Select-String/various string methods, Where clauses/etc.

Powershell and registry key changing challenge

I make changes under hklm with a line like this:
Set-Location HKLM:\software\afilefolder\afilefolder
and it works. I also need to make a change to a current user key, I am told to do this by making a change to hkey_users, but i have about 5 machines that would run this script and based on what machine it is, i need to make a change to my location, because hkey_users has an sid as the next file folder and it changes for each user. so based on the user, i grab the sid, I have all of them. and i set my location like this:
$test = "hkey_users\" + $hkeypath + "\filefolder\filefolder"
Set-Location $test
I cannot put the concatenation in the Set-Location line, powershell no likey, but when I do it this way, it says the following path cannot be found: C:\windows\system32\HKEY_USERS\correctsid\filefolder\filefolder
why does it look in the system32 folder? how do i make changes to hkey_user. please advise
You can set the location just fine, with the string concatenation, just put the whole thing in the double quotes. You'll want to reference that it's in the registry just to be safe, try this out:
Set-Location "registry::hkey_users\$hkeypath\filefolder\filefolder"
That worked for me (well, I set my SID to $mysid and then did a Set-Location "registry::hk_users\$mysid\software" and that got me to my software key in the registry, under my SID).