I need to save a single data item in a registry key to a variable. I've tried the following without any luck:
$dxVersion = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\DirectX").GetValue("Version",$null)
I want JUST the version number saved to the variable, nothing else. Not the name, just the data.
Thanks in advance for your help!
You almost had it. Try:
$dxVersion = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\DirectX").Version
Get-ItemProperty returns a PSCustomObject with a number of properties -- Version among them. This sort of dotted notation as I used above allows you to quickly access the value of any property.
Alternatively, so long as you specify a scalar property, you could use the ExpandProperty parameter of Select-Object:
$dxVersion = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\DirectX") | Select-Object -ExpandProperty Version
Related
Similar posts such as this one or this one explain how to get a remote registry key, but it assumes that you already know the name of the value that you are interested in. If you run
Get-ItemProperty "HKLM:\Software\MySoftware"
It will return all properties and their corresponding values, but Get-ItemProperty doesn't work for remote machines. If you want to do the same for a remote registry key you can use the [Microsoft.Win32.RegistryKey] approach but that is only half the answer. As an example:
$Reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $myServer)
$RegKey= $Reg.OpenSubKey("SOFTWARE\\MySoftware")
$RegKey will become a System.MarshalByRefObject. This means that it is not the actual key but rather just opens up the ability to continue asking for more information from that key. Using the $RegKey.GetValue() requires you to know the value you want to fetch, but what if you want to fetch all values for the key but you don't know how many values there are, or their names? How would you go about doing this?
After you have opened the $RegKey you can use the following:
$RegKey.GetValueNames()
This will produce a list of all item properties and their values. You can then loop through that list with a foreach to retrieve the value for all of the item properties like:
foreach($ItemProperty in $RegKey.GetValueNames()){
$RegKey.GetValue($ItemProperty)
}
Bonus: If you want to export this to, say, a CSV file you can create a custom PS object and export this to a CSV file as follows:
foreach($ItemProperty in $RegKey.GetValueNames()){
$myObject = [PSCustomObject]#{
ItemProperty = $ItemProperty
Value = $RegKey.GetValue($ItemProperty)
} | Export-Csv "yourpath\yourfile.csv" -Append -Delimiter "|" -NoTypeInformation
}
What is the output format of Get-ADComputer? I'm trying to do something like this to take an inventory.
[string[]]$server_list = Get-ADComputer -Filter * -Property Name # Select-Object Name
However, when I use $server_list in a foreach, I see the object curly brackets like so
foreach ($machine_name in $server_list) {
"processing : $machine_name";
}
output:
#{Name=some-machine-name-123-here}
I just need the actual name value, how do i get that?
The -Property Name parameter is unnecessary, as Get-ADComputer always retrieves the Name property. (This doesn't select only the Name property, as you seem to have thought.)
Rather than -Property Name, append | Select-Object -ExpandProperty Name to your Get-ADComputer command line.
So, my query returned a different result. Thus you might need to do a little work on this.
Basically, -Property says that you want an object with a certain field. Select does more or less the same thing.
If you want to keep your existing solution, expand the property instead of selecting it. This is the best way to do that:
[string[]]$server_list = (Get-ADComputer -Filter * -Property Name).Name
You returned #{} which is powershell's way of representing an object inside a string. In this case, an object that contains properties about your ADComputers, of which you chose to only include "Name". If you included additional properties, you would see a larger comma separated list of type=value.
You can actually remove -Property Name, however this will take longer to run, since you're filtering on the right. (Gathering a lot of data and THEN filtering it to only Name.)
I have been successfully using [environment]::getfolderpath("ProgramFiles") to get the path to program Files, but now I have a need to also access Program Data, and it looks from this enumeration like ProgramData is not available with this method. Is that true, or am I missing something here?
$env: to access environmental variables
$env:ProgramData
The quickest way is to use $env:ProgramData as BenH already pointed out in your question comments.
Using the .net Specialfolder, you would have needed to use the CommonApplicationData
Instead of using a string though such as your initial example:
[Environment]::GetFolderPath('CommonApplicationData')
I'd suggest using the enumeration as you will get the possible enumeration values directly into the intellisense while developping.
[Environment]::GetFolderPath([System.Environment+SpecialFolder]::CommonApplicationData)
Finally, because you knew the path you were looking for but not the corresponding variable, you could have listed them all neatly using something like:
$SpecialFolders = New-Object -TypeName psobject
[Environment+SpecialFolder]::GetNames([Environment+SpecialFolder]) | sort |
foreach {Add-Member -InputObject $SpecialFolders -Type NoteProperty -Name
($_) -Value ([Environment]::GetFolderPath($_)) }
$SpecialFolders | fl
Using that snippet, you could have determined that c:\programdata was a special folder path belonging to CommonApplicationData.
The enumeration can still be handy if a specified folder is not in the $env scope (example: My documents special folder).
When I use the Select-Object Name CmdLet it seems to create a new object with a single Name property on it.
I often want to pipe this selection to other CmdLets but they often take just a string.
How can I easily get a bunch of objects and say "Select only property x and just the property values into an array or collection of just its values"?
You can use the ExpandProperty parameter for this. This switch means that instead of returning an object with properties as listed on the (default) -Properties parameter, the value of the single property listed under -ExpandProperty parameter is returned.
NB: You can also use the alias, expand for this parameter.
Example:
Get-Process | Select-Object -ExpandProperty ProcessName
Related documentation:
SS64: https://ss64.com/ps/select-object.html
MS Docs: https://learn.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Utility/Select-Object?view=powershell-3.0
I have an example code snippet that suggests using
(Get-Process | Where-Object {$_.WorkingSet64 -gt 20mb}).Count
to return the count of all processess using > 20Mb.
It works, but when typing, neither Intellisense or the "Tab" key shows this property, rather they show the properties of an individual process - which I find misleading.
I understand, that specifying an item property will give me the list of that property only, but is there a way to easily see, in general, what ALL the valid propeties are, including list aggregates etc?
Even assigning to a variable
$processes = Get-Process | Where-Object {$_.WorkingSet64 -gt 20mb}
does not show me "Count" as a valid property of $processes until AFTER the assignment has been actually run and the value assigned - when writing the script it still shows the properties for an individual item.
For me, Intellisense / Tab help that does not cover all the options kind of defeats the purpose ... (not having to remember hundreds objects/functions and their properties / parameters).
Is there any way to improve this situation? Some syntax trick have I missed?
The correct way to find out all of the properties of an object is to pipe the output to Get-Member:
Get-Process | Get-Member
Sometimes there are hidden properties and methods that can only be seen if you add the -force switch:
Get-Process | Get-Member -Force
The count property is an automatic property that is always usable on any collection object but that isn't explicitly listed as a property. Another example of an automatic property is length.
Using #() to force an array type is handy when that is what is wanted.
e.g. $processes = #(Get-Process | Where-Object {$_.WorkingSet64 -gt 20mb}). will show you "Count" and the other array properties.
Other than that, let's say the Intellisense has various limitations / shortcomings that I will just have to learn... sigh.