Registry Archives - i Love PowerShell https://ilovepowershell.com/tag/registry/ I came. I saw. I automated. Fri, 14 Apr 2023 15:09:21 +0000 en-US hourly 1 https://wordpress.org/?v=6.6.2 https://ilovepowershell.com/wp-content/uploads/2020/09/SiteLogo-150x150.png Registry Archives - i Love PowerShell https://ilovepowershell.com/tag/registry/ 32 32 System Information: Getting Hardware, Software, and OS Details https://ilovepowershell.com/powershell-basics/system-information-getting-hardware-software-os-details-how-to/ Fri, 14 Apr 2023 12:14:41 +0000 https://ilovepowershell.com/?p=3307 Gathering system information is a crucial aspect of system administration, as it helps you understand the resources and components of your infrastructure. In this article, we will explore how to use PowerShell to gather hardware, software, and operating system details on Windows, macOS, and Linux systems. In this article, I want to give you a […]

The post System Information: Getting Hardware, Software, and OS Details appeared first on i Love PowerShell.

]]>
Gathering system information is a crucial aspect of system administration, as it helps you understand the resources and components of your infrastructure. In this article, we will explore how to use PowerShell to gather hardware, software, and operating system details on Windows, macOS, and Linux systems.

In this article, I want to give you a glimpse into using PowerShell for gathering system information, but I also want to show how awesome PowerShell is across various operating systems.

Now, system administrators work with all kinds of environments, and it’s helpful to see some of those differences. As you’ve seen, there are some unique aspects when it comes to using PowerShell on Windows, macOS, and Linux.

My goal is to help you navigate these distinctions and offer practical guidance, tips, and examples to make your PowerShell experience more seamless, no matter the platform you’re working with.

Let’s continue to explore and learn together, leveraging PowerShell’s powerful capabilities to enhance our system administration expertise.

Gathering Operating System Information

The Get-CimInstance cmdlet is a cross-platform tool that allows you to query and retrieve information about your system using CIM classes. Although some CIM classes are Windows-specific, many of them can be used on macOS and Linux as well.

Getting System Information from Get-CimInstance

Here’s an example of how to use the Get-CimInstance cmdlet to retrieve OS information:

$os = Get-CimInstance -ClassName CIM_OperatingSystem
$os | Select-Object Caption, Version, OSArchitecture, BuildNumber

This command retrieves information such as the OS version, architecture, and build number.

Nice, but you have to already know the ClassName, right?

Wrong!

PowerShell provides a way to discover available CIM classes using the Get-CimClass cmdlet. Let me show you real quick how the process of finding the right CIM classes and namespaces to gather system information works.

Listing CIM Classes

You can list all available CIM classes by running the Get-CimClass cmdlet without any parameters:

Get-CimClass

This command will return a long list of CIM classes, so it’s usually better to narrow down your search using wildcards.

Searching CIM Classes with Wildcards

You can use the -ClassName parameter with wildcards to filter the list of CIM classes. For example, to find classes related to disk drives, you can use the following command:

Get-CimClass -ClassName *disk*

This will return a list of CIM classes with “disk” in their names, such as CIM_DiskDrive and CIM_LogicalDisk.

Exploring Specific CIM Classes

Once you’ve found a CIM class of interest, you can further explore its properties and methods using the Get-CimClass cmdlet. For example, to see the properties and methods available for the CIM_Processor class, you can run:

Get-CimClass -ClassName CIM_Processor

Discovering WMI Namespaces

CIM classes are organized in WMI namespaces. To list the available namespaces on your system, you can use the Get-WmiObject cmdlet with the -Namespace parameter and wildcards:

Get-WmiObject -Namespace root\* -Class __Namespace | Select-Object Name

This command will return a list of available namespaces under the “root” namespace.

Searching CIM Classes within a Specific Namespace

You can combine the -Namespace parameter with the Get-CimClass cmdlet to search for CIM classes within a specific namespace. For example, to find classes related to networking in the “root\cimv2” namespace, you can run:

Get-CimClass -Namespace root\cimv2 -ClassName *network*

This will return a list of CIM classes related to networking within the “root\cimv2” namespace.

By leveraging the Get-CimClass and Get-WmiObject cmdlets, you can discover the available CIM classes and namespaces to gather the system information you need. With this knowledge, you can really ramp up your efficiency with being able to specifically target individual components for your system administration tasks from your PowerShell scripts.

Gathering Hardware Information

Alright, now that we have cleared up some of the relationship between CimClass and CimInstance, let’s dig into how we can pull hardware information out of the system.

Using the Get-CimInstance cmdlet, you can also obtain hardware information on Windows, macOS, and Linux systems. Here are some examples:

Processor Information

$processor = Get-CimInstance -ClassName CIM_Processor
$processor | Select-Object Name, MaxClockSpeed

Memory Information

$memory = Get-CimInstance -ClassName CIM_PhysicalMemory
$memory | Select-Object Capacity, Speed

Disk Drives

$diskDrives = Get-CimInstance -ClassName CIM_DiskDrive
$diskDrives | Select-Object Model, MediaType, Size

Logical Disks

$logicalDisks = Get-CimInstance -ClassName CIM_LogicalDisk
$logicalDisks | Select-Object DeviceID, FileSystem, Size, FreeSpace

Network Adapters

$networkAdapters = Get-CimInstance -ClassName CIM_NetworkAdapter
$networkAdapters | Select-Object Name, MACAddress, Speed

BIOS Information

$bios = Get-CimInstance -ClassName CIM_BIOSElement
$bios | Select-Object Manufacturer, Version, ReleaseDate

Battery information (for laptops/tablets)

$battery = Get-CimInstance -ClassName CIM_Battery
$battery | Select-Object EstimatedChargeRemaining, EstimatedRunTime

Graphics card info

$graphics = Get-CimInstance -ClassName CIM_VideoController
$graphics | Select-Object Name, AdapterRAM, DriverVersion

In some cases, you might need to rely on platform-specific commands or tools for macOS and Linux to gather certain system information.

Gathering Software Information

Gathering software installation information from your system can be a little more complicated. That’s because the software details can be accessed from a few different locations.

So here is a little tour of the madness that can be listing all the software installed on a system:

Capturing from Software Package Managers

If you use Chocolatey or Winget for installing software, you’re used to a command line approach and you’re already a leg up on people that are only familiar with the old “next next next” installation style.

You can use those same package managers to list what software is installed on your system.

### Chocolatey List Locally Installed Software

choco list --local-only

### Windows Package Manager (Winget)

winget list

### Packages installed through PowerShell (mostly modules)

Get-Package

Querying WMI

Just like you can use the CIM cmdlets to query WMI to get hardware information, you can use it similarly to get software information.

Get-CimInstance -ClassName Win32_Product | Select-Object Name, Version

However, be aware that using the Win32_Product class can cause performance issues and unintended side effects, such as triggering a reconfiguration of installed software. A safer alternative is to query the registry:

Querying the Registry

In Windows systems, everything is in the registry. I’ve got another article on how to read, set and even (carefully!) delete registry keys. Take a look at that if you’re not familiar with the commands for working with the registry. You can also leverage the PowerShell providers to browse the registry like a folder structure.

Either way, for this case you’re going to want to look at both the 32-bit and 64-bit software sections in the registry to capture a full list of software that’s installed.

$keys = @("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
          "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*")

$installedSoftware = $keys | ForEach-Object { Get-ItemProperty $_ } |
    Where-Object { $_.DisplayName -ne $null } |
    Select-Object DisplayName, DisplayVersion, Publisher

$installedSoftware

Finding Software Information on Mac / Linux

Both Linux and Mac have similar package manager stories as Windows does with Chocolatey & Winget. It’s even a little more straightforward as it’s been used for so long, while it’s relatively new for Windows users.

So you’ll still end up using your package manager commands to list the installed software on PowerShell. However, the great thing about PowerShell is how it works with objects… And the sad thing is that the package managers only output text.

If you want to create a more Object-centric result, you could parse the text that is returned to turn it into an object. That could look something like this:

# macOS example
$softwareList = brew list --formula
$softwareObjects = $softwareList | ForEach-Object {
  [PSCustomObject]{
    Name = $_
    Version = (brew info --formula $_ | Select-String -Pattern "stable\s+(\S+)").Matches.Groups[1].Value
  }
}

# Linux example (Debian-based)
$softwareList = dpkg --list
$softwareObjects = $softwareList | Select-String -Pattern "^(ii\s+)(\S+)(\s+\S+\s+)(\S+)" | ForEach-Object {
  [PSCustomObject]@{
    Name = $.Matches.Groups[2].Value
    Version = $.Matches.Groups[4].Value
  }
}

Hopefully that gives you a fun thing to play with when looking for your software on Linux/Mac. Play with it and let me know how it goes!

Gathering System Information with Custom PowerShell Scripts

You can create custom PowerShell scripts to collect specific system information tailored to your needs. Here’s an example of a script that collects system information and exports it to a CSV file:

$systemInfo = [PSCustomObject]@{
    OS = (Get-CimInstance -ClassName CIM_OperatingSystem).Caption
    Processor = (Get-CimInstance -ClassName CIM_Processor).Name
    Memory = (Get-CimInstance -ClassName CIM_PhysicalMemory).Capacity
    DiskSpace = (Get-CimInstance -ClassName CIM_LogicalDisk).Size
}

$systemInfo | Export-Csv -Path "SystemInfo.csv" -NoTypeInformation

Exporting and Saving System Information

PowerShell provides several cmdlets for exporting and saving system information in different formats, such as Export-Csv, Export-Clixml, and Out-File. Here’s an example of exporting hardware information to a CSV file:

$hardwareInfo = Get-CimInstance -ClassName CIM_ComputerSystem
$hardwareInfo | Export-Csv -Path "HardwareInfo.csv" -NoTypeInformation

Conclusion

We all know that PowerShell is the best language for working with system administration on Windows. But with these cross platform tools and cmdlets, PowerShell is a great tool for working with any Operating System.

By using the Get-Cim* cmdlets instead of the older Get-Wmi* cmdlets, you can take advantage of cross-platform compatibility, improved performance, and more efficient memory usage. Continue practicing and exploring further system information tasks with PowerShell to enhance your skills and better manage your infrastructure.

The post System Information: Getting Hardware, Software, and OS Details appeared first on i Love PowerShell.

]]>
3307
Windows Registry with PowerShell: Reading, Writing and Deleting Keys https://ilovepowershell.com/powershell-basics/windows-registry-reading-writing-and-deleting-keys-how-to/ Mon, 10 Apr 2023 19:47:41 +0000 https://ilovepowershell.com/?p=3299 The Windows Registry is a hierarchical database that stores configuration settings and options for the Windows operating system, applications, and hardware devices. In this article, we will explore how to manage the Windows Registry using PowerShell, including reading, writing, and deleting registry keys and values. The Absolutely Necessary Warning Section on Messing with Your Registry […]

The post Windows Registry with PowerShell: Reading, Writing and Deleting Keys appeared first on i Love PowerShell.

]]>
The Windows Registry is a hierarchical database that stores configuration settings and options for the Windows operating system, applications, and hardware devices. In this article, we will explore how to manage the Windows Registry using PowerShell, including reading, writing, and deleting registry keys and values.

The Absolutely Necessary Warning Section on Messing with Your Registry

Modifying the registry carries certain risks, as incorrect changes can lead to system instability or application malfunctions. You can seriously screw up your OS, or – with PowerShell and remote management – all of the servers that you’re trying to fix!

To HELP REDUCE THESE RISKS – consider the following:

  • Perform registry exports and backups before making changes. You can use the reg export command in the Command Prompt or PowerShell to export registry keys to a .reg file. Alternatively, you can use the Export-Clixml cmdlet to save registry key information to an XML file, which is available in cross-platform PowerShell 7:

I think for a registry export I would probably just use the dos command. The PowerShell isn’t doing anything very special here, no extra functionality and I would just keep it simple. Still, there could be a good use case for doing it all in PowerShell with the import/export functionality.

Here’s the PowerShell code to export the reg keys into an XML format.

$key = Get-Item -Path "HKLM:\SOFTWARE\ExampleKey"
$key | Export-Clixml -Path "ExampleKeyBackup.xml"

To import the saved information, you can use the Import-Clixml cmdlet:

$importedKey = Import-Clixml -Path "ExampleKeyBackup.xml

# Recreate the registry key
New-Item -Path $importedKey.PSPath -Force

# Recreate the registry values
foreach ($property in $importedKey.Property) {
    $value = $importedKey.GetValue($property)
    Set-ItemProperty -Path $importedKey.PSPath -Name $property -Value $value
}

This script imports the XML content into a PowerShell object, recreates the registry key using the New-Item cmdlet, and then iterates through the properties to recreate the registry values using the Set-ItemProperty cmdlet. You can see that the PowerShell version of this import starts to get more complicated, where importing the registry backup that was created with the reg export command is more strait-forward:

If you have exported the registry key using the reg export command, you will get a .reg file. Importing a .reg file is different from importing an XML file. To import a .reg file, you can use the reg import command in the Command Prompt or PowerShell:

  1. Open an elevated Command Prompt or PowerShell (Run as Administrator).
  2. Import the .reg file with the reg import command.
reg import "Path\to\your\ExampleKeyBackup.reg"

This command will merge the contents of the .reg file into the registry.

Keep in mind that using the reg import command can overwrite existing registry keys and values. Always make sure to backup the current state of your registry before importing a .reg file to avoid potential issues.

  • Use the -WhatIf parameter on PowerShell cmdlets to preview changes before executing them. This parameter simulates the cmdlet’s actions without making any actual changes, allowing you to review the potential impact before proceeding. It’s not always perfect, but it’s there and can definitely help to guide you or warn you off making a change that you didn’t intend.

Ok, now if I haven’t scared you off of the whole idea, let’s get to the good parts!

Accessing the Windows Registry with PowerShell

PowerShell includes a Registry Provider (read all about Powershell providers if you are wondering), which allows you to access and manage the registry just like a file system. The provider exposes registry hives as drives:

  • HKLM: HKEY_LOCAL_MACHINE
  • HKCU: HKEY_CURRENT_USER
  • HKCR: HKEY_CLASSES_ROOT
  • HKU: HKEY_USERS
  • HKCC: HKEY_CURRENT_CONFIG

To access registry keys, you can use the registry drive notation. For example, to access the HKEY_LOCAL_MACHINE hive, you can use the following command:

cd HKLM:

Reading Registry Keys and Values

To read registry keys and values, you can use the Get-Item and Get-ItemProperty cmdlets. The following example retrieves a registry key and its values:

powershell
$key = Get-Item -Path "HKLM:\SOFTWARE\ExampleKey"
$values = Get-ItemProperty -Path $key.PSPath

Creating and Modifying Registry Keys and Values

To create or modify registry keys and values, you can use the New-Item, Set-Item, and Set-ItemProperty cmdlets. The following example creates a new registry key and sets a value:

$key = New-Item -Path "HKLM:\SOFTWARE\ExampleKey"
Set-ItemProperty -Path $key.PSPath -Name "ExampleValue" -Value "Sample Data"

Deleting Registry Keys and Values

To delete registry keys and values, you can use the Remove-Item and Remove-ItemProperty cmdlets. The following example deletes a registry value and then the key:

Remove-ItemProperty -Path "HKLM:\SOFTWARE\ExampleKey" -Name "ExampleValue"
Remove-Item -Path "HKLM:\SOFTWARE\ExampleKey"

Best Practices and Precautions

  • Always back up the registry before making changes to reduce the risk of unintended consequences.
  • Run PowerShell with administrative privileges when modifying the registry to ensure you have the necessary permissions.
  • Test registry changes on non-production systems first to confirm their effects and avoid unexpected issues on critical systems.

Conclusion

PowerShell provides a powerful and flexible way to manage the Windows Registry, making it an essential tool for system administrators. By understanding the cmdlets and best practices covered in this article, you can confidently read, write, and delete registry keys and values while minimizing potential risks. As you continue to develop your PowerShell skills, explore further registry management tasks and incorporate them into your daily workflow.

The post Windows Registry with PowerShell: Reading, Writing and Deleting Keys appeared first on i Love PowerShell.

]]>
3299
How to Check if a Server Needs a Reboot https://ilovepowershell.com/windows-powershell-legacy/how-to-check-if-a-server-needs-a-reboot/ https://ilovepowershell.com/windows-powershell-legacy/how-to-check-if-a-server-needs-a-reboot/#respond Thu, 10 Sep 2015 23:26:15 +0000 https://ilovepowershell.com/?p=2407 If you’re trying to determine which of your servers require reboots, you’ll love this PowerShell script to check the status. It turns out that a simple way to identify servers that are pending reboot is to check the registry. This information is stored in the HKeyLocalMachine hive of the registry. PowerShell is perfect for working […]

The post How to Check if a Server Needs a Reboot appeared first on i Love PowerShell.

]]>
If you’re trying to determine which of your servers require reboots, you’ll love this PowerShell script to check the status.

It turns out that a simple way to identify servers that are pending reboot is to check the registry.

This information is stored in the HKeyLocalMachine hive of the registry.

PowerShell is perfect for working with the registry.

Registry is one of the built-in PowerShell providers!

There’s even already a PSDrive connected to that registry hive!

You can’t ask for anything more… except to maybe be able to map a new PSDrive to a different part of the Registry — which is ALSO super easy to do!

You can browse around the registry just like you do with the filesystem.

#Change to the registry drive. 
#Set-Location can also be invoked through its aliases - CD and SL
#Get-ChildItem can also be invoked through its aliases - Dir and LS

Set-Location HKLM:
Get-ChildItem

Wow! Super easy, right?

Now you just need to know where the “pending reboot” location is. There are a couple of places to check.

  • HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired

Is where patches installed through automatic updates register the need to reboot.

  • HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending

Is another place where pending reboots can be identified.

  • HKLM\SYSTEM\CurrentControlSet\Control\Session Manager

Is yet another. Finally, there is Configuration Manager which, if present, can be queried via WMI.

I found a function that I really like to check all four locations.

I’ll need to wrap it up with some parameters to check remote computers, but in general it was a great start.

I’ve adapted the function to return $true on the first condition that satisfies, since I only care about whether the computer is pending a reboot, and not where the source of the reboot is coming from.

#Adapted from https://gist.github.com/altrive/5329377
#Based on <https://gallery.technet.microsoft.com/scriptcenter/Get-PendingReboot-Query-bdb79542>
function Test-PendingReboot
{
 if (Get-ChildItem "HKLM:\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending" -EA Ignore) { return $true }
 if (Get-Item "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired" -EA Ignore) { return $true }
 if (Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Name PendingFileRenameOperations -EA Ignore) { return $true }
 try { 
   $util = [wmiclass]"\\.\root\ccm\clientsdk:CCM_ClientUtilities"
   $status = $util.DetermineIfRebootPending()
   if(($status -ne $null) -and $status.RebootPending){
     return $true
   }
 }catch{}

 return $false
}

The post How to Check if a Server Needs a Reboot appeared first on i Love PowerShell.

]]>
https://ilovepowershell.com/windows-powershell-legacy/how-to-check-if-a-server-needs-a-reboot/feed/ 0 2407