Extracting registrykey properties to an array [SOLVED]

by mannappie at 2012-09-16 04:09:58

Hello all! I hope you can help me with my "little" problem.

As I’m a beginner with powershell I hope my question is not to challenging for you guys. I’m at a loss… Not even the internet could help me out…

I’m trying to get the properties (names and values) from a registry hive out of the registry and in an array for work later on.
The key is HKLM:\SYSTEM\MountedDevices<br>
I tried several methods to try this but none of them worked. I tried:
$key = "HKLM:\SYSTEM\MountedDevices&quot;
$Properties = @()
$Properties=Get-ItemProperty -path $Key
$Properties


This is the console output:
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices<br>PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SYSTEM
PSChildName : MountedDevices
PSDrive : HKLM
PSProvider : Microsoft.PowerShell.Core\Registry
\DosDevices\C: : {73, 214, 52, 208…}
\DosDevices\D: : {96, 186, 131, 239…}
\DosDevices\E: : {186, 135, 141, 27…}
\DosDevices\H: : {96, 186, 131, 239…}
\DosDevices\I: : {68, 77, 73, 79…}
\DosDevices\J: : {96, 118, 76, 69…}
\DosDevices\G: : {92, 0, 63, 0…}
\DosDevices\K: : {68, 77, 73, 79…}
\DosDevices\N: : {95, 0, 63, 0…}
\DosDevices\O: : {95, 0, 63, 0…}
\DosDevices\F: : {92, 0, 63, 0…}
\DosDevices\L: : {73, 214, 52, 208…}
??\Volume{cc891c87-a774-11e1-ac64-806e6f6e6963} : {96, 186, 131, 239…}
??\Volume{cc891c88-a774-11e1-ac64-806e6f6e6963} : {96, 186, 131, 239…}
??\Volume{cc891c89-a774-11e1-ac64-806e6f6e6963} : {73, 214, 52, 208…}
??\Volume{cc891c8a-a774-11e1-ac64-806e6f6e6963} : {73, 214, 52, 208…}
??\Volume{cc891c8b-a774-11e1-ac64-806e6f6e6963} : {186, 135, 141, 27…}
??\Volume{cc891c90-a774-11e1-ac64-806e6f6e6963} : {92, 0, 63, 0…}
??\Volume{5c557625-a7fb-11e1-8a10-806e6f6e6963} : {95, 0, 63, 0…}
??\Volume{04986547-aaee-11e1-a44d-002618f1c991} : {92, 0, 63, 0…}
??\Volume{1cc70bd0-b959-11e1-a68a-002618f1c991} : {96, 118, 76, 69…}
??\Volume{1cc70bd3-b959-11e1-a68a-002618f1c991} : {84, 114, 117, 101…}
??\Volume{afc1c797-bd0a-11e1-a137-002618f1c991} : {95, 0, 63, 0…}
??\Volume{afc1c79d-bd0a-11e1-a137-002618f1c991} : {95, 0, 63, 0…}
??\Volume{afc1c79f-bd0a-11e1-a137-002618f1c991} : {95, 0, 63, 0…}
\DosDevices\P: : {95, 0, 63, 0…}
??\Volume{afc1c7a1-bd0a-11e1-a137-002618f1c991} : {95, 0, 63, 0…}
\DosDevices\Q: : {95, 0, 63, 0…}
??\Volume{e49f12f4-bdd4-11e1-9206-005056c00008} : {95, 0, 63, 0…}
??\Volume{7d1ec9ac-bf72-11e1-a89e-005056c00008} : {95, 0, 63, 0…}
#{02896ea0-c8cf-11e1-a893-005056c00008} : {84, 114, 117, 101…}
??\Volume{4116a17e-cd85-11e1-a8fe-005056c00008} : {95, 0, 63, 0…}
\DosDevices\M: : {95, 0, 63, 0…}
??\Volume{f6db67a1-d23f-11e1-a8f2-005056c00008} : {95, 0, 63, 0…}
??\Volume{3939f078-ebc0-11e1-a8e9-005056c00008} : {95, 0, 63, 0…}

Since I’m only interested in the driveletters, I would like to filter for "DosDevices".
None of my methodes worked. It looks like I end up with a single string inside the array and not an array with two elements.

If (I hope when) I could the above solved, I would like to convert the binary value into readable text and add that to the array as yet another element.

If someone could give me some help, it would be much apreciated!
by RichardSiddaway at 2012-09-16 06:29:54
This will get the data into an array.
$data = @()
Get-Item -Path HKLM:\SYSTEM\MountedDevices |
select -ExpandProperty Property |
where {$_ -like "\Dos*"} |
foreach {
$name = $
$data += New-Object -TypeName psobject -Property @{
Device = $name
Value = (Get-ItemProperty -Path HKLM:\SYSTEM\MountedDevices -Name $name)."$name"
}

}
$data



is this the direction you wanted to go?
by mannappie at 2012-09-16 11:34:17
Wow! Yep exactly that!

Many many thanks!
That really solves my first problem, but now for the second. Since the value is reg_binary and furthermore in unicode. Would there be anyway for the script to convert that into readable text and store that in the same array?
by RichardSiddaway at 2012-09-16 12:10:01
Try this

$data = @()
Get-Item -Path HKLM:\SYSTEM\MountedDevices |
select -ExpandProperty Property |
where {$
-like "\Dos*"} |
foreach {
$name = $
$bin = (Get-ItemProperty -Path HKLM:\SYSTEM\MountedDevices -Name $name)."$name"

$decoded = @()
$bin | foreach {
$decoded += [char]$

}


$data += New-Object -TypeName psobject -Property @{
Device = $name
BinaryValue = $bin
DecodedValue = $($decoded -join "")
}

}
$data | Format-Table Device, DecodedValue -AutoSize
by mannappie at 2012-09-17 04:51:40
Thanks again for the help!! Your time helping me is much appreciated!!!

I can see it working. The variables get filled with the right information but something goes wrong when @data gets displayed. My guess would be that it is because of some of the (mathmetical) characters that are decoded.
I’ve encountered that behaviour before, but my powershell skills aren’t up to the challenge.

One of the troublemakers is: " ??\SCSI#CdRom&Ven_HL-DT-ST&Prod_BD-RE__BNH10LS38#4&2…etc"
by poshoholic at 2012-09-17 07:26:20
Do you get better results if you decode your Unicode byte arrays like this instead?
$decoded = [System.Text.Encoding]]
by mannappie at 2012-09-17 07:52:55
I’ll try it when I’m home. I will get back to you.
by mannappie at 2012-09-17 13:20:16
Tried your suggestion. It does change some things while encoding, but the problem remains.

Since I don’t need the special characters we could change those to something else that doesn’t cause problems and then put the changed string in the array. If you could point me in the right direction again?
by poshoholic at 2012-09-17 16:24:07
I just did a quick search and found an article that indicates in the byte arrays for DOS devices, the first 4 bytes are the drive signature and the last 8 bytes are the partition offset on that drive. Here’s the article I found: http://diddy.boot-land.net/firadisk/files/mounteddevices.htm. With that article in mind you shouldn’t be converting this to a string because the data would be meaningless. Well, sort of. You can convert an array of bytes into a string by simply taking that value and applying the -join operator to it. For example:
$byteArray -join ','
Is that what you want to store?
by mannappie at 2012-09-17 22:47:23
Well, ofcourse you’re right. But the data, for me anyway, is far from meaningless. Inside the value the serialnumber of a usb-drive is shown. My ultimate goal is to search through the array for the serialnumber using information I get elsewhere. I then know what driveletter was assigned to that drive the last time it was plugged in.

Back on the script again: :wink:
I think it would be possible to change the questionmarks and other signs to something that can be stored before actualy storing them in the array. I’ll try a couple of things. If you have any suggestions it would be appreciated. You’re scripting skills are awesome!
by mannappie at 2012-09-18 03:26:44
$data = @()

Get-Item -Path HKLM:\SYSTEM\MountedDevices |
select -ExpandProperty Property |
where {$_ -like "\Dos*"} |

foreach {
$name = $
$bin = (Get-ItemProperty -Path HKLM:\SYSTEM\MountedDevices -Name $name)."$name"
$decode = @()
$decoded = @()

$bin | foreach {
if ($
-contains "00"){
$testchar = ""
}else{

$testchar = [char]$_


if ($testchar -contains "?"){
$testchar = ""
}
if ($testchar -contains "/"){
$testchar = "
"
}
if ($testchar -contains "#"){
$testchar = ""
}
if ($testchar -contains "-"){
$testchar = "
"
}
if ($testchar -contains "&"){
$testchar = "_"
}
}
$decode += $testchar
}
$decoded = $($decode -join "")

$data += New-Object -TypeName psobject -Property @{
Device = $name
BinaryValue = $bin
DecodedValue = $decoded
}

}
$data | Format-Table Device, BinaryValue, DecodedValue -AutoSize



This is what I’ve come up with. I guess it isn’t pretty, so additions and improvements are always welcome. I’m just glad it works :slight_smile:
Apperently the "00" was the problem. As soon as I filtered those out, the script worked great!. Thanks again for all the help. I hope I can knock on your door again :wink:
by poshoholic at 2012-09-18 06:11:52
Glad you got it worked out!