The post System Information: Getting Hardware, Software, and OS Details appeared first on i Love PowerShell.
]]>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.
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.
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.
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.
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.
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.
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
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.
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.
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 = Get-CimInstance -ClassName CIM_Processor $processor | Select-Object Name, MaxClockSpeed
$memory = Get-CimInstance -ClassName CIM_PhysicalMemory $memory | Select-Object Capacity, Speed
$diskDrives = Get-CimInstance -ClassName CIM_DiskDrive $diskDrives | Select-Object Model, MediaType, Size
$logicalDisks = Get-CimInstance -ClassName CIM_LogicalDisk $logicalDisks | Select-Object DeviceID, FileSystem, Size, FreeSpace
$networkAdapters = Get-CimInstance -ClassName CIM_NetworkAdapter $networkAdapters | Select-Object Name, MACAddress, Speed
$bios = Get-CimInstance -ClassName CIM_BIOSElement $bios | Select-Object Manufacturer, Version, ReleaseDate
$battery = Get-CimInstance -ClassName CIM_Battery $battery | Select-Object EstimatedChargeRemaining, EstimatedRunTime
$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 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:
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
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:
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
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!
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
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
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.
]]>The post Windows Registry with PowerShell: Reading, Writing and Deleting Keys appeared first on i Love PowerShell.
]]>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:
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:
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.
-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!
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:
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:
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
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"
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"
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.
]]>The post PowerShell for Networks: Pinging, Testing, and Scanning appeared first on i Love PowerShell.
]]>In this article, we will explore how to use PowerShell for doing some of the basic network related tests that you’re going to want to perform. Pinging hosts, testing network connectivity, and scanning ports are all important aspects of understanding what is going on with a system that is having issues. This article is intended for system administrators who are learning PowerShell and are familiar with the basics of network components: That is, I expect you already understand what you’re trying to do, I’m just going to show you how to do those things with PowerShell.
Hey, to follow along with the examples in this article, you need to have PowerShell 7 installed on your system. PowerShell 7 is cross-platform, so it can be used on Windows, macOS, and Linux. We recommend using Visual Studio Code (VSCode) as your editor, as it provides excellent support for PowerShell scripting with syntax highlighting, code completion, and integrated debugging.
Ok, with that out of the way, let’s get into pinging and testing networks with PowerShell
Pinging hosts is a fundamental network troubleshooting technique used to test the reachability of a host on an IP network. In PowerShell, you can use the Test-Connection cmdlet to ping hosts and gather information about the network path between your system and the target host.
Test-Connection cmdletHere’s how you use the Test-Connection cmdlet to ping a computer.
# Ping a single host Test-Connection -TargetName www.example.com
Test-ConnectionHere are a few use cases for how you could use Test-Connection in your daily administration and troubleshooting.
# Ping multiple hosts
$hosts = @("www.example.com", "www.google.com", "www.bing.com")
foreach ($host in $hosts) { Test-Connection -TargetName $host -Count 1 -Quiet }
The code above shows how you can use Test-Connection to ping multiple hosts. It does them one at a time using a Foreach loop. Every host in the array of hostnames is pinged with Test-Connection.
The Test-Connection parameters used here are:
-TargetName: Specifies the target host to ping. In this case, it’s the $host variable.-Count: Defines the number of echo requests to send. Here, it is set to 1, meaning only one ping request is sent to each host.-Quiet: When this switch is used, the cmdlet returns a boolean value (True or False) instead of detailed ping results. If the host is reachable and responds to the ping, the cmdlet returns True; otherwise, it returns False.In this example, we use Test-Connection to test network latency by measuring the response time for ICMP echo requests (ping) to a target host.
$targetHost = "www.example.com" $pingCount = 5 $results = Test-Connection -TargetName $targetHost -Count $pingCount $averageLatency = ($results | Measure-Object -Property ResponseTime -Average).Average $maxLatency = $results | Sort-Object ResponseTime -Descending | Select -First 1 -ExpandProperty ResponseTime $minLatency = $results | Sort-Object ResponseTime | Select -First 1 -ExpandProperty ResponseTime "Average latency to $targetHost: $($averageLatency) ms" "Fastest response: $($minLatency) ms" "Slowest response: $($maxLatency) ms"
This script sends 5 ping requests to www.example.com and calculates the average latency based on the response times. It also shows the fastest and slowest response to the host. This information can help troubleshoot issues related to network latency, such as slow website loading or delayed response times in applications.
This example checks if specific ports are open and accepting connections on a target host. This can help identify firewall or network issues that may be blocking traffic.
$targetHost = "www.example.com"
$ports = @(80, 443, 21)
foreach ($port in $ports) {
$result = Test-Connection -TargetName $targetHost -Port $port -Count 1 -Quiet
if ($result) {
"Port $port is open on $targetHost"
} else {
"Port $port is closed on $targetHost"
}
}
The script checks connectivity on ports 80, 443, and 21 on www.example.com. If a port is open, it displays a message indicating that the port is open; if it’s closed, it displays a message indicating that the port is closed.
This could be used to not just test FTP and Web Servers, but testing a larger set of known ports, like SSH (22) and SQL Server (1433).
You can also use Test-Connection with the -Traceroute switch to trace the network path from the source system to a target host. This can help identify issues related to network routing or intermediate network devices.
$targetHost = "www.example.com"
$tracerouteResults = Test-Connection -TargetName $targetHost -Traceroute
foreach ($result in $tracerouteResults) {
"Hop $($result.Hop) - $($result.Source) - $($result.ProtocolAddress) - $($result.ResponseTime) ms"
}
This script performs a traceroute to www.example.com and displays the hop number, source IP, destination IP, and response time for each hop in the network path. Traceroute results can really be helpful if you want to identify potential routing problems or network bottlenecks that may affect network performance.
Test-Connection has a great option for testing a network connection with different buffer sizes in order to validate network performance. By comparing the response times for different buffer sizes, you can determine how your network handles larger packets and identify potential performance issues.
$targetHost = "www.example.com"
$bufferSizes = @(32, 512, 1024, 2048)
foreach ($bufferSize in $bufferSizes) {
$result = Test-Connection -TargetName $targetHost -Count 1 -BufferSize $bufferSize
"Response time with buffer size $($bufferSize) bytes: $($result.ResponseTime) ms"
}
This script sends a single ping request to www.example.com using four different buffer sizes (32, 512, 1024, and 2048 bytes) and displays the response time for each test. By analyzing the results, you can identify if larger packets experience higher latency or other network performance issues.
Test-Connection can be used to test connectivity to an IPv6 address in a similar way as an IPv4 address. In addition to testing connectivity, this can also help you confirm that your network supports IPv6 connectivity and troubleshoot potential IPv6-related issues.
$targetHostIPv6 = "2001:0db8:85a3:0000:0000:8a2e:0370:7334"
$results = Test-Connection -TargetName $targetHostIPv6 -Ping -Count 3
foreach ($result in $results) {
"Response from $($result.Address) - $($result.ResponseTime) ms"
}
This script sends three ping requests to an IPv6 address (2001:0db8:85a3:0000:0000:8a2e:0370:7334) and displays the response times for each request. The -Ping switch is used to force the use of ICMP echo requests, even when targeting an IPv6 address. This can help you verify IPv6 connectivity and identify potential issues related to IPv6 addressing or routing.
Test-NetConnection Test-Connection does a great job of performing network and diagnostic testing. AND… It’s cross-platform, so you can use it in Windows, Linux and Mac. So for me, even though I have a lot of muscle memory with Test-NetConnection I’ve made the switch to using Test-Connection. But Test-NetConnection, which came first and was available in Windows for several versions, does include some detailed diagnostics that keep it handy to know on Windows machines.
# Test connectivity to a host on a specific port Test-NetConnection -ComputerName www.example.com -Port 80
For the basic use, the syntax is the same as using the cross-platform Test-Connection. Even some of the other parameters are the same, so that options like testing for multiple ports works as described above.
# Scan ports on multiple hosts
$hosts = @("www.example.com", "www.google.com")
$portRange = 80..90
foreach ($host in $hosts) {
foreach ($port in $portRange) {
Test-NetConnection -ComputerName $host -Port $port
}
}
If it’s basically the same as Test-Connection, but it’s Windows-only, what am I missing? Why use Test-NetConnection at all? Great question! And it has some great answers, too.
A big part of it is in the output object. Both Test-Connection and Test-NetConnection give you the same basic details, but the actual objects are quite different.
The objects returned by Test-NetConnection provide more detailed diagnostic information compared to the objects returned by Test-Connection. Some specific advantages of the NetConnectionTestResult objects returned by Test-NetConnection are:
Test-NetConnection returns properties like InterfaceAlias and InterfaceIndex, which provide information about the network interface used for the connection test. This can be helpful when troubleshooting network issues on systems with multiple network interfaces.Test-NetConnection returns more specific error messages in the Diagnosis property when a connection test fails. This can be helpful in identifying the cause of a connectivity issue, such as a closed port or a routing problem.Test-NetConnection returns the TcpTestSucceeded property, which is a Boolean value indicating whether the TCP connection test succeeded or failed. Additionally, the TcpState property provides the actual state of the TCP connection, such as “Established” or “Closed,” which can help in understanding the status of a connection more precisely.Test-NetConnection combines the functionality of several cmdlets, such as Resolve-DnsName, Test-Connection, and Get-NetAdapter, into a single output object. This allows you to get a more comprehensive view of the network connection and its related properties without having to use multiple cmdlets and parse their output separately.So the NetConnectionTestResult objects returned by Test-NetConnection provides more detailed diagnostic information, which can make it easier to identify and troubleshoot network issues on Windows systems.
In addition to the basic network management tasks covered in this article, PowerShell provides cmdlets for working with DNS records, managing network interfaces, and monitoring network traffic. While we won’t go into detail in this article, I’ll mention them here, and you can explore them more as you continue your PowerShell journey.
Resolve-DnsName and Get-DnsClientCache that allow you to resolve DNS names, clear the DNS cache, and perform other DNS-related tasks.Get-NetAdapter, Enable-NetAdapter, and Disable-NetAdapter to manage network interfaces on your system, enabling or disabling them as needed.Get-NetTCPConnection and Get-NetUDPEndpoint that enable you to monitor network traffic and examine the status of TCP and UDP connections on your system.As you work with PowerShell for network management tasks, try to keep these good habits in mind:
As you progress in your PowerShell learning, remember the importance of practicing and developing new skills. Consider finding a mentor, enrolling in a course, or exploring additional resources and documentation to expand your knowledge. The more you practice, the more proficient you will become in PowerShell and its various features.
In this article, we have explored using PowerShell for network management tasks such as pinging hosts, testing network connectivity, and scanning ports. As you continue your PowerShell journey, experiment with these techniques and explore more advanced network management tasks. By doing so, you will become a more effective and efficient system administrator, able to leverage the full power of PowerShell to manage your organization’s network infrastructure.
The post PowerShell for Networks: Pinging, Testing, and Scanning appeared first on i Love PowerShell.
]]>The post Monitoring Processes with Custom Performance Counters appeared first on i Love PowerShell.
]]>Whether you’re trying to improve performance, make better use of resources, or just trying to track down some issue that’s causing an error on your system, when you’re working with your Windows OS, you’re going to be spending a lot of time working with processes. And process monitoring is an important aspect of working with processes. It can really highlight the issue quickly when you can identify which running process is consuming all of the CPU or RAM.
In this article, we will explore custom performance counters in PowerShell and how they can be used to monitor processes in a more tailored manner. This article is intended for system administrators who are learning PowerShell and are familiar with the basics of processes running on Windows.
This article was written assuming that you’re running PowerShell 7, with VS Code as your editor and the PowerShell extension. PowerShell 7 is cross-platform, so it can be used on Windows, macOS, and Linux. We recommend using Visual Studio Code (VSCode) as your editor, as it’s just an awesome environment for doing anything with PowerShell – it has an integrated terminal, intellisense, and great debugging tools. If you’re not running with this setup yet, well – it’s time to get started! Here’s basic instructions on how to install PowerShell for Windows, Mac or Linux
Windows provides built-in performance counters that allow you to monitor various aspects of processes, such as CPU usage, memory consumption, and I/O operations. PowerShell is pretty great at making these counters accessible from the command line using easy command syntax. They can be accessed using the Get-Counter cmdlet. However, built-in performance counters may not cover every monitoring requirement, especially when you need to track custom metrics or specific application behavior. This is where custom performance counters become essential.

When I’m digging deep into performance counters
Custom performance counters gives system administrators and IT professionals some serious power to amp up their monitoring game. Really, anything is possible. So when would you use it? Some common use cases include:
Before you can create a custom performance counter, you must define a custom performance counter category. This category will serve as a container for your custom counters, making them easier to manage and organize.
Custom performance counter categories are groupings of related custom performance counters. They help you organize your custom counters and provide a logical structure for accessing them.
To create your category, you need to define its name, description, and the counters it will contain. Then, you can register it using the [System.Diagnostics.PerformanceCounterCategory]::Create() method.
$categoryName = "CustomProcessMonitor" $categoryHelp = "A custom category for monitoring specific process aspects" $counterName = "CustomCounter" $counterHelp = "A custom counter for process monitoring" $counterType = [System.Diagnostics.PerformanceCounterType]::NumberOfItems32 # Register the custom performance counter $counterData = New-Object System.Diagnostics.CounterCreationData($counterName, $counterHelp, $counterType) $counterDataCollection = New-Object System.Diagnostics.CounterCreationDataCollection $counterDataCollection.Add($counterData) [System.Diagnostics.PerformanceCounterCategory]::Create($categoryName, $categoryHelp, $counterDataCollection)
Now that you have a custom performance counter category, you can create custom performance counters within it. Custom performance counters are user-defined counters that track specific metrics or aspects of processes. They can be used to monitor application-specific information, resource usage trends, or any other custom data you need to track.
To create a custom performance counter, you need to define its name, description, and type. You can then register the counter within your custom performance counter category.
$process = Start-Process "notepad.exe" -PassThru # Update the custom performance counter $counter = New-Object System.Diagnostics.PerformanceCounter($categoryName, $counterName, $process.ProcessName, $false) $counter.RawValue = 0
This code block does two things:
$process = Start-Process "notepad.exe" -PassThruThis line starts a new instance of Notepad and assigns the process information to the $process variable. The -PassThru switch is used to return the process object, allowing you to access its properties and methods.$counter = New-Object System.Diagnostics.PerformanceCounter($categoryName, $counterName, $process.ProcessName, $false)
$counter.RawValue = 0
The New-Object cmdlet is used to create a new instance of the System.Diagnostics.PerformanceCounter class. The constructor for this class accepts four arguments:
$categoryName: The name of the custom performance counter category that the counter belongs to.$counterName: The name of the custom performance counter.$process.ProcessName: The name of the process that the custom performance counter is associated with. In this case, it is the name of the Notepad process started earlier.$false: A boolean value indicating whether the counter is read-only. By setting it to $false, we are allowing the counter to be updated.After creating the PerformanceCounter object and storing it in the $counter variable, the code sets the counter’s RawValue property to 0, initializing the counter value.
Now that we have the custom counter created, reading it is the easy part. We can read it just like we would any other performance counter! To read the value, use the Get-Counter cmdlet with the counter’s path.
Get-Counter cmdlet with custom countersTo read one of your new perf counter values, you need to provide the correct counter path, which includes the computer name, custom category name, process name, and counter name. It looks like this:
# Reading the custom performance counter from PowerShell $counterPath = "\\" + $env:COMPUTERNAME + "\$categoryName($($process.Name))\$counterName" $counterValue = Get-Counter -Counter $counterPath $counterValue.CounterSamples.CookedValue
This code is helpful in showing how to create a performance counter… but this code doesn’t really help us with anything. It shows how to monitor something that is set manually to the number “zero”.
Here are some more helpful things that you could monitor with the custom performance counter:
CPU usage: Monitor the percentage of CPU time consumed by the process.
$processCpuCounter = New-Object System.Diagnostics.PerformanceCounter("Process", "% Processor Time", $process.Name)
$counter.RawValue = [int]$processCpuCounter.NextValue()
Working set size (memory usage): Monitor the amount of memory used by the process.
$counter.RawValue = $process.WorkingSet64
Private bytes: Monitor the amount of private memory allocated to the process.
$privateBytesCounter = New-Object System.Diagnostics.PerformanceCounter("Process", "Private Bytes", $process.Name)
$counter.RawValue = [int]$privateBytesCounter.NextValue()
Number of threads: Monitor the number of threads used by the process.
$counter.RawValue = $process.Threads.Count
Handle count: Monitor the number of handles (file, registry, etc.) used by the process.
$counter.RawValue = $process.HandleCount
To use any of these use cases, replace the line $counter.RawValue = 0 in the original script with the corresponding code block for the desired performance metric. Note that some of these counters require a delay or a loop to get accurate values, especially the ones that use the NextValue() method.
When working with custom performance counters, keep the following best practices in mind:
As you continue learning PowerShell, remember the importance of practicing and developing new skills. Consider finding a mentor, enrolling in a course, or exploring additional resources and documentation to expand your knowledge. The more you practice, the more proficient you will become in PowerShell and I swear it can change your career!
In this article, we have explored custom performance counters in PowerShell, which can help you monitor processes in a more tailored manner. We have covered the creation of custom performance counter categories and counters, updating and reading custom counters, and discussed some best practices for using custom performance counters. As you continue your PowerShell journey, keep experimenting and learning to get the most out of this powerful scripting language.
The post Monitoring Processes with Custom Performance Counters appeared first on i Love PowerShell.
]]>The post PowerShell for Process Management: Starting, Stopping, and Monitoring Processes appeared first on i Love PowerShell.
]]>And no matter what the OS is, there are already built in tools for working with those processes. But with PowerShell, you have a couple of cmdlets that are made for working with processes, making it easy to start, stop and administer the processes that are running on your machine.
So do you need PowerShell to do this? Well, in a way, you don’t. But what PowerShell does is bundle up all of the automation and functionality AROUND the process management. Filtering processes in a list, and then taking appropriate actions on just the processes that you care about (or are bugging you (warning – OLD post link alert 🙂
But I want to make sure that if you are new to PowerShell, that you can continue to build on your skills of working with the commands, and that you can work with processes in a familiar way to other PowerShell commands. We’ll walk you through each step with clear explanations and code snippets. Remember, learning new skills and practicing regularly are essential for mastering PowerShell.
In this article I assume that you’re working with PowerShell 7 or later, and that you’re using Visual Studio Code as your editor. This is a great, cross platform approach and you should be able to follow along with everything from that setup. You should also have the PowerShell extension installed in VS Code. If you need any help you can read installation instructions for PowerShell on Linux, Mac or Windows.
You’re going to want to start any exploration into processes with looking at what’s already running. This is very easy with PowerShell. Just use the Get-Process cmdlet.
For example, to list all running processes:
Get-Process
To filter processes by name or ID, use the -Name or -Id parameters, respectively:
Get-Process -Name "notepad" Get-Process -Id 1234
To start processes, use the Start-Process cmdlet. For example, to start Notepad:
Start-Process "notepad.exe"
To start a process with arguments and a specific working directory:
Start-Process "cmd.exe" -ArgumentList "/c dir" -WorkingDirectory "C:\temp"
To run a process in the background or with elevated privileges, use the -NoNewWindow or -Verb parameters:
Start-Process "powershell.exe" -NoNewWindow -ArgumentList "-Command Get-Process" Start-Process "powershell.exe" -Verb "RunAs" -ArgumentList "-Command Get-Process"
To stop processes, use the Stop-Process cmdlet. For example, to stop a process by its ID:
Stop-Process -Id 1234
Or you could stop processes by their name:
Stop-Process -Name "notepad"
And if you need to apply a little more pressure to forcibly stop the process, you can use the -Force parameter:
Stop-Process -Name "notepad" -Force
Alright, here we get into something a little less “basic”. You might have a need to query a little more information about a running process, and PowerShell is great at helping you to do that.
To monitor processes, use the Get-Counter cmdlet. For example, to monitor the CPU and memory usage of a process:
Get-Counter -Counter "\Process(notepad)\% Processor Time", "\Process(notepad)\Working Set"
I cover some more pieces of process monitoring and working with counters and events in Troubleshooting with PowerShell: Event Logs, Performance Counters, and More. Taking approaches to elevate your understanding of the processes running on the system and really digging into the OS level is definitely a deep topic but one that can help you to really establish yourself as an expert at your job.
Of course, PowerShell is all about automation and management. So you can definitely use this to your advantage when you’re included these operations in your scripts and functions.
Combining tasks in a script allows you to automate process management tasks. For example, to start a process, monitor its resource usage, and stop it after a certain threshold is reached:
$process = Start-Process "notepad.exe" -PassThru
$threshold = 1000000
while ($true) {
$memoryUsage = (Get-Process -Id $process.Id).WorkingSet
if ($memoryUsage -gt $threshold) {
Stop-Process -Id $process.Id
break
}
Start-Sleep -Seconds 5
}
If you like to use PowerShell to automate system resources, you should check out another (warning: another OLD article alert!) 😁How to Setup a PowerShell Script to Run as a Scheduled Task
-WhatIf parameter to preview the result of a command before executing it, helping to prevent unintentional changes or data loss.As you continue learning PowerShell, practice and apply your new skills to real-world scenarios. Seek out a mentor or enroll in a course to deepen your understanding of PowerShell. Explore additional resources, such as the official PowerShell documentation and community forums, to learn about new cmdlets and techniques.
In this article, we covered the basics of process management using PowerShell, including viewing, starting, stopping, and monitoring processes. Keep practicing and applying these skills to become more proficient in using PowerShell for various tasks. PowerShell is a powerful tool that can help you automate tasks, manage systems, and troubleshoot issues, so continue exploring and building your skills – it’s going to make you a better professional as you include more DevOps concepts into your daily work!
The post PowerShell for Process Management: Starting, Stopping, and Monitoring Processes appeared first on i Love PowerShell.
]]>The post PowerShell for File Management: Copying, Moving, and Deleting Files appeared first on i Love PowerShell.
]]>PowerShell is a powerful scripting language and automation tool that is essential for system administrators. One of the critical tasks administrators perform is managing files across the file system. In this article, we will cover the basics of file management using PowerShell, including copying, moving, and deleting files.
As a beginner, you might find some of the concepts challenging, but don’t worry; we’ll walk you through each step with clear explanations and code snippets. Remember, learning new skills and practicing regularly are the keys to mastering PowerShell.
Before diving into file management tasks, ensure that you have PowerShell 7 installed on your system. PowerShell 7 is cross-platform and works with Windows, macOS, and Linux.
You’ll also want to install Visual Studio Code (VSCode). VSCode is a versatile and powerful code editor that is perfect for working with PowerShell scripts. Make sure you have the PowerShell extension installed in VSCode for enhanced PowerShell support.
To navigate the file system in PowerShell, you can use the Set-Location cmdlet (alias: cd). For example, to change the current directory to “C:\temp”:
Set-Location "C:\temp"
To list the files and folders in the current directory, use the Get-ChildItem cmdlet (alias: ls or dir):
Get-ChildItem
To copy files, use the Copy-Item cmdlet. For example, to copy a file called “file.txt” from the current directory to a folder called “backup”:
Copy-Item "file.txt" -Destination "backup"
To copy multiple files, use wildcards:
Copy-Item "*.txt" -Destination "backup"
This command copies all “.txt” files from the current directory to the “backup” folder.
To move files, use the Move-Item cmdlet. For example, to move a file called “file.txt” from the current directory to a folder called “archive”:
Move-Item "file.txt" -Destination "archive"
To move multiple files based on a condition, use the Where-Object cmdlet (alias: ?):
Get-ChildItem "*.log" | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-7) } | Move-Item -Destination "old_logs"
This command moves all “.log” files older than 7 days to the “old_logs” folder.
To delete files, use the Remove-Item cmdlet. For example, to delete a file called “file.txt”:
Remove-Item "file.txt"
To delete multiple files with a specific extension, use wildcards:
Remove-Item "*.bak" -Force
This command deletes all “.bak” files in the current directory. The -Force parameter is used to suppress confirmation prompts.
You can combine tasks to create powerful scripts. For example, to copy all “.txt” files to a “backup” folder and then delete the original files:
Copy-Item "*.txt" -Destination "backup" Remove-Item "*.txt"
As you continue learning PowerShell, remember the importance of practicing and applying your new skills to real-world scenarios. Seek out a mentor or enroll in a course to deepen your understanding of PowerShell.
Explore additional resources, such as the official PowerShell documentation and community forums, to learn about new cmdlets and techniques.
In this article, we covered the basics of file management using PowerShell, including navigating the file system, copying, moving, and deleting files. As you practice and apply these skills, you’ll become more proficient in using PowerShell for various tasks.
Keep learning, experimenting, and discovering new techniques to become a more effective and efficient system administrator. PowerShell is a powerful tool that can help you automate tasks, manage systems, and troubleshoot issues, so keep exploring and building your skills.
The post PowerShell for File Management: Copying, Moving, and Deleting Files appeared first on i Love PowerShell.
]]>The post Troubleshooting with PowerShell: Event Logs, Performance Counters, and More appeared first on i Love PowerShell.
]]>To view event logs with PowerShell, you can use the Get-WinEvent cmdlet. This cmdlet retrieves events from event logs, including classic logs and the newer event tracing logs. To get events from the System log, for example:
Get-WinEvent -LogName System
Get-WinEvent provides a powerful filtering mechanism using the -FilterHashtable parameter. For example, to retrieve only Error events from the Application log:
Get-WinEvent -FilterHashtable @{ LogName='Application'; Level=2 }
You can create custom event logs to record application-specific events. To create a new event log, use the New-EventLog cmdlet:
New-EventLog -LogName "CustomLog" -Source "MyApp"
PowerShell provides the Get-Counter cmdlet to access performance counters. For example, to retrieve the current processor time percentage:
Get-Counter -Counter "\Processor(_Total)\% Processor Time"
You can monitor performance counters in real-time by using the -Continuous parameter and specifying an update interval with the -SampleInterval parameter:
Get-Counter -Counter "\Processor(_Total)\% Processor Time" -Continuous -SampleInterval 5
Export performance counter data to a CSV file for further analysis:
$counterData = Get-Counter -Counter "\Processor(_Total)\% Processor Time" -MaxSamples 10 $counterData | Export-Counter -Path "performance_data.csv" -FileFormat CSV
Use the Get-Service cmdlet to list all services on a system:
Get-Service
To start, stop, or restart a service, use the Start-Service, Stop-Service, and Restart-Service cmdlets, respectively:
Start-Service -Name "MyService" Stop-Service -Name "MyService" Restart-Service -Name "MyService"
Monitor a service status by filtering the output of Get-Service:
Get-Service -Name "MyService" | Select-Object -Property Status, Name, DisplayName
Use the Get-Process cmdlet to list all running processes on a system:
Get-Process
You can filter and sort the process list based on specific criteria, such as memory usage or CPU time:
Get-Process | Where-Object { $_.WorkingSet64 -gt 100MB } | Sort-Object -Property CPU -Descending
To terminate a process, use the Stop-Process cmdlet:
Stop-Process -Name "Notepad" -Force
PowerShell is a versatile and powerful tool for troubleshooting system issues. By understanding how to work with event logs, performance counters, services, and processes, you will become more effective in diagnosing and resolving problems on your systems. As always, practice and continued learning are essential to mastering PowerShell. Consider enrolling in a PowerShell course or finding a mentor to help you further develop your troubleshooting skills. As you gain proficiency, you’ll find that PowerShell is an indispensable tool in your System Administrator toolkit.
The post Troubleshooting with PowerShell: Event Logs, Performance Counters, and More appeared first on i Love PowerShell.
]]>The post PowerShell Security: Execution Policies, Certificates, and Signing appeared first on i Love PowerShell.
]]>Before we dive into the specifics of PowerShell security, it’s worth taking a moment to emphasize the importance of learning PowerShell as a system administrator. PowerShell is a versatile and powerful language that allows you to automate many common administrative tasks. By learning PowerShell, you can save time and increase efficiency, while also gaining more control over your systems. Additionally, as a System Administrator, PowerShell is the best language choice for managing Windows systems, and a really strong choice for managing ANY system. So, investing time in learning PowerShell is a wise decision that can pay dividends for your career and your organization.
However, as with any powerful tool, it’s important to use PowerShell responsibly and securely. Fortunately, PowerShell provides several security features that can help mitigate potential risks.
The first and most basic security feature in PowerShell is the execution policy. Execution policies define what types of scripts can be run on a system. By default, PowerShell has a restrictive execution policy that prevents the execution of any script. This is to prevent malicious scripts from running without the user’s knowledge or consent. However, this default policy can be too restrictive for some scenarios, so it’s important to understand how to set and check execution policies to allow the execution of trusted scripts.
Execution policies in PowerShell define what types of scripts can be run on a system. They are essentially a security feature that helps prevent the execution of malicious scripts. By default, PowerShell has a restrictive execution policy that prevents the execution of any script. However, in many cases, you will need to run trusted scripts on your system, so it’s important to understand how to set and check execution policies.
There are several levels of execution policies in PowerShell, each with its own set of rules for script execution. These levels include:
To set an execution policy in PowerShell, you can use the Set-ExecutionPolicy cmdlet. For example, to set the execution policy to RemoteSigned, you can use the following command:
Set-ExecutionPolicy RemoteSigned
To check the current execution policy, you can use the Get-ExecutionPolicy cmdlet. For example, to check the current execution policy, you can use the following command:
Get-ExecutionPolicy
Execution policies can be overridden on a script-by-script basis by using the -ExecutionPolicy parameter when running a script. This allows you to temporarily bypass the execution policy for a specific script, without changing the system-wide policy.
So wrapping up on execution policies, they are an important security feature in PowerShell that help prevent the execution of malicious scripts. By understanding the different execution policy levels and how to set and check them, you can ensure that your system is secure while still allowing the execution of trusted scripts.
Certificates are another important security feature in PowerShell. Certificates are digital documents that are used to authenticate the identity of a person, organization, or device. In PowerShell, certificates can be used to secure communications, sign scripts, and authenticate PowerShell sessions.
There are several types of certificates that can be used in PowerShell, including:
To create a certificate in PowerShell, you can use the New-SelfSignedCertificate cmdlet. For example, to create a self-signed certificate, you can use the following command:
New-SelfSignedCertificate -Subject "CN=MyTestCertificate"
This will create a new self-signed certificate with the subject “CN=MyTestCertificate”. You can then use this certificate to secure communications or sign PowerShell scripts.
Signing PowerShell scripts is an important aspect of PowerShell security. Script signing ensures that scripts have not been tampered with since they were created and that they come from a trusted source. In order to sign a PowerShell script, you will need a code signing certificate.
Code signing certificates are digital certificates that are used to sign code, such as PowerShell scripts. They ensure that the code has not been tampered with and that it comes from a trusted source. You can obtain a code signing certificate from a trusted certificate authority, such as Digicert or Comodo. Alternatively, you can create a self-signed certificate using the New-SelfSignedCertificate cmdlet in PowerShell.
Once you have a code signing certificate, you can use it to sign your PowerShell scripts. To sign a script, you will need to use the Set-AuthenticodeSignature cmdlet. This cmdlet takes two parameters: the path to the script and the certificate that you want to use to sign the script.
Here’s an example of how to sign a script with a code signing certificate:
Set-AuthenticodeSignature -FilePath C:\Scripts\MyScript.ps1 -Certificate (Get-ChildItem -Path Cert:\CurrentUser\My -CodeSigningCert)
In this example, we’re signing a script called MyScript.ps1 located in the C:\Scripts directory. We’re using the certificate from the current user’s certificate store that has the CodeSigningCert property set to True. Once the script is signed, it will have a digital signature that can be verified using the Get-AuthenticodeSignature cmdlet.
It’s important to note that script signing is not foolproof. It’s still possible for malicious code to make its way onto a system, especially if the attacker has administrative privileges. However, script signing is an important security measure that can help prevent many types of attacks.
PowerShell provides many powerful tools and features that make it an excellent choice for system administrators. However, with great power comes great responsibility, and it’s important to understand the security features of PowerShell to ensure that your systems are safe from potential attacks.
In this article, we’ve discussed some of the key security features of PowerShell, including execution policies, certificates, and signing. We’ve seen how execution policies can help prevent unauthorized scripts from running, how certificates can be used to sign scripts and ensure their authenticity, and how signing scripts can help prevent malicious code from being executed.
We’ve also emphasized the importance of staying up-to-date with PowerShell security best practices and keeping your system and software updated to ensure that you are protected against known vulnerabilities.
By taking these steps to secure your PowerShell environment, you can feel confident that your system is protected against potential threats. And with PowerShell’s powerful capabilities, you can streamline your administrative tasks and become more efficient in your work. So, take the time to learn PowerShell and its security features, and reap the benefits of this versatile and powerful tool.
The post PowerShell Security: Execution Policies, Certificates, and Signing appeared first on i Love PowerShell.
]]>The post PowerShell Errors and Debugging: Handling, Tracing and Logging appeared first on i Love PowerShell.
]]>PowerShell error handling is an essential concept to understand when working with PowerShell scripts. Error handling refers to the process of detecting, responding to, and recovering from errors that occur while running PowerShell commands or scripts. PowerShell errors can occur for various reasons, such as syntax errors, runtime errors, or logical errors.
PowerShell provides the ErrorAction parameter to control how errors are handled within a script or command. This parameter allows you to set the action that PowerShell should take when an error occurs. One of the options available is “SilentlyContinue”, which tells PowerShell to suppress the error message and continue with the script or command.
For example, consider the following command that attempts to stop a service named “MyService”:
Stop-Service -Name MyService
If the service is not running, PowerShell will generate an error message stating that the service could not be stopped. However, if you add the ErrorAction parameter with a value of “SilentlyContinue”, PowerShell will not display the error message and will continue running the script:
Stop-Service -Name MyService -ErrorAction SilentlyContinue
Keep in mind that blocking errors in this way can make it difficult to identify and troubleshoot problems within your scripts. It’s generally better to use try/catch/finally blocks to handle errors and take appropriate actions based on the type of error that occurred.
PowerShell provides various error-handling mechanisms to help you manage errors that occur while running PowerShell commands or scripts. One of the primary mechanisms is the use of the try-catch-finally statement. The try-catch-finally statement enables you to catch errors that occur while running PowerShell commands or scripts and take appropriate actions to handle those errors.
try {
# Attempt to execute some code here
$result = Get-Item -Path "C:\Some\File\Path"
Write-Host "File exists"
}
catch {
# Handle any errors that occur here
Write-Host "An error occurred: $($_.Exception.Message)"
}
finally {
# Clean up resources or perform any final actions here
Write-Host "This code block always executes, regardless of whether an exception was caught or not."
}
In this example, the try block attempts to get the item located at the specified file path. If this code executes successfully, the $result variable is populated with the item object and a message is written to the console. If an error occurs, the catch block handles the exception and writes an error message to the console. Finally, the finally block executes regardless of whether an exception was caught or not, and performs any necessary cleanup actions.
Note that in a try-catch-finally block, the catch and finally blocks are optional. You can use a try block on its own, or include one or both of the other blocks as necessary for your code.
Using the try-catch-finally statement provides more control over how PowerShell handles errors and allows you to execute specific code when an error occurs. By handling errors explicitly, you can make your PowerShell scripts more robust and reliable. In the next section, we will explore PowerShell error tracing and logging, which can help you diagnose and troubleshoot errors that occur while running PowerShell scripts.
Debugging is the process of identifying and resolving errors or bugs in a script or program. PowerShell provides several tools and techniques for debugging, making it easier to diagnose and fix issues in your scripts. In this section, we will explore some of the most useful PowerShell debugging features.
PowerShell includes a debug mode that you can enable to step through your code line-by-line and examine variables and expressions as you go. To enter debug mode, add the -Debug switch to your PowerShell command or function. For example:
function Get-MyData {
[CmdletBinding()]
param()
Write-Debug "Getting data..."
$data = Get-Data
Write-Debug "Data retrieved."
return $data
}
In this example, the Write-Debug cmdlet is used to output debugging messages to the console. When the Get-MyData function is executed with the -Debug switch, these messages will be displayed in the console along with the output of the function.
Another powerful debugging feature in PowerShell is breakpoints. Breakpoints allow you to pause the execution of your script at a specific line or statement and examine the state of your variables and expressions. To set a breakpoint, use the Set-PSBreakpoint cmdlet. For example:
function Get-MyData {
[CmdletBinding()]
param()
Write-Debug "Getting data..."
$data = Get-Data
Write-Debug "Data retrieved."
return $data
}
Set-PSBreakpoint -Script Get-MyData -Line 5
Get-MyData -Debug
In this example, we set a breakpoint on line 5 of the Get-MyData function using the Set-PSBreakpoint cmdlet. When the function is executed with the -Debug switch, it will pause at line 5, allowing you to examine the value of $data and other variables at that point in the script.
Visual Studio Code provides excellent support for PowerShell debugging. To start debugging a PowerShell script in Visual Studio Code, open the script in the editor and press F5. This will launch the script in debug mode, and you can set breakpoints, examine variables, and step through your code using the Debug toolbar.
Visual Studio Code also provides several helpful features, such as the ability to evaluate expressions and variables in the Debug Console and the ability to debug PowerShell scripts remotely on other machines.
In addition to outputting debugging messages to the console, you can also write them to a log file using the Start-Transcript cmdlet. This cmdlet starts a transcript of the PowerShell session and writes all output to a specified file. For example:
Start-Transcript -Path "C:\Logs\MyScript.log" Write-Debug "Starting script..." # rest of script here Stop-Transcript
In this example, we start a transcript of the PowerShell session using the Start-Transcript cmdlet and specify the output file using the -Path parameter. All output, including debugging messages, will be written to the specified log file. Once the script is complete, the transcript can be stopped using the Stop-Transcript cmdlet.
Overall, PowerShell provides several useful tools and techniques for debugging scripts and identifying and resolving errors. By using features such as debug mode, breakpoints, and logging, you can make the debugging process faster and more efficient, helping you to write better PowerShell scripts.
PowerShell tracing is a powerful feature that allows users to log each command, its parameters, and its output, which can help debug and troubleshoot PowerShell scripts. PowerShell tracing provides visibility into how a script is executed and what values are passed to commands.
PowerShell tracing can be enabled by using the Start-Transcript cmdlet. This cmdlet creates a transcript of all PowerShell command activity in a session. The Start-Transcript cmdlet takes a file path as its argument and saves the transcript to the specified file.
Start-Transcript -Path "C:\Logs\transcript.log"
This command starts a transcript and saves it to “C:\Logs\transcript.log”. All commands executed after this cmdlet will be logged to this file until Stop-Transcript is called.
Stop-Transcript
This command stops the transcript and saves it to the file specified in Start-Transcript.
In addition to the Start-Transcript and Stop-Transcript cmdlets, PowerShell also provides a built-in tracing feature called Verbose. The Verbose parameter can be used to provide additional information about the execution of a script. When the Verbose parameter is used with a command, PowerShell writes additional information about the command execution to the console.
Get-ChildItem -Path C:\Users -Verbose
This command lists all the files and directories in the C:\Users directory and displays additional information about the operation on the console.
PowerShell also provides a built-in tracing feature called Debug. The Debug parameter can be used to track the execution of a script, command, or function by logging messages to the console. When the Debug parameter is used, PowerShell logs messages to the console that provide information about the execution of the script.
Set-Variable -Name MyVariable -Value "My Value" -Debug
This command sets a variable named “MyVariable” to “My Value” and logs a message to the console indicating that the command is executing.
In addition to these built-in tracing features, PowerShell also supports a number of third-party tracing tools that can help users diagnose and troubleshoot PowerShell scripts. Some popular tools include PSScriptAnalyzer, PowerShell Studio, and Visual Studio Code.
Overall, PowerShell tracing is a powerful feature that can help users diagnose and troubleshoot PowerShell scripts. By using PowerShell tracing, users can log each command, its parameters, and its output, which provides visibility into how a script is executed and what values are passed to commands.
PowerShell provides an easy and convenient way to log events to the Windows Event Logs. Logging to the Event Logs allows administrators to easily view and analyze logs across multiple systems, as the Event Logs are stored in a central location. In this section, we will explore how to log events to the Windows Event Logs using PowerShell.
To log events to the Windows Event Logs, we will use the Write-EventLog cmdlet. This cmdlet allows us to create and write entries to any event log on a local or remote computer. The basic syntax of the cmdlet is as follows:
Write-EventLog -LogName <string> -Source <string> -EventId <int> `
[-EntryType {Error | Warning | Information | SuccessAudit | FailureAudit}] [-Message <string>] ` # Optional parameters
[-Category <int>] [-RawData <byte[]>] [-ComputerName <string>] # More optional parameters
Let’s break down the parameters:
LogName: specifies the name of the event log to write to, such as “Application” or “System”.Source: specifies the name of the application or component that is writing to the log.EventId: specifies the numeric ID of the event.EntryType: specifies the type of event being logged. Valid values are Error, Warning, Information, SuccessAudit, and FailureAudit.Message: specifies the text of the event message.Category: specifies the numeric category of the event.RawData: specifies binary data to be associated with the event.ComputerName: specifies the name of the remote computer to write to. If not specified, the cmdlet writes to the local computer.Let’s take a look at an example. Suppose we want to log an event to the Application log with a source of “MyApp”, an ID of 100, and an information level. The message will say “MyApp started successfully.” We can do this with the following command:
Write-EventLog -LogName Application -Source MyApp -EventId 100 -EntryType Information -Message "MyApp started successfully."
This will create an entry in the Application log that looks something like this:
Log Name: Application Source: MyApp Date: 1/31/2023 12:00:00 PM Event ID: 100 Task Category: None Level: Information Keywords: Classic User: N/A Computer: MyComputer Description: MyApp started successfully.
As you can see, the log entry contains the specified source, event ID, and message. It also includes the date, time, and computer name.
In addition to the basic parameters, Write-EventLog also supports some additional options, such as logging binary data and specifying a custom message file.
When logging to the Windows Event Logs, it’s important to follow best practices for event log management, such as regularly reviewing logs, setting appropriate retention policies, and monitoring for suspicious activity. By logging PowerShell events to the Windows Event Logs, you can easily track the activity of your PowerShell scripts and quickly identify and respond to any issues that arise.
PowerShell provides various tools and techniques to help you identify and troubleshoot errors in your scripts, functions, and modules. By understanding PowerShell’s error handling capabilities, you can gracefully handle exceptions, customize error messages, and write more robust code.
Debugging in PowerShell allows you to step through your code and identify errors by viewing variables, function calls, and more. Additionally, PowerShell’s tracing and logging capabilities can help you gain insight into the execution of your code and enable you to identify issues that may not be apparent through traditional debugging methods.
In this article, we’ve covered how to handle errors in PowerShell using try-catch blocks, how to debug PowerShell scripts, and how to use tracing and logging to diagnose issues. By implementing these techniques in your PowerShell scripts, you can ensure that your code is more reliable, maintainable, and less prone to errors.
Remember to always follow best practices when writing PowerShell scripts, such as using descriptive variable names, including comments, and regularly testing your code. With the right tools and techniques, PowerShell can be a powerful tool for automation and administration in any environment.
The post PowerShell Errors and Debugging: Handling, Tracing and Logging appeared first on i Love PowerShell.
]]>The post PowerShell Remoting: Connecting to Remote Systems appeared first on i Love PowerShell.
]]>In this article, we will explore how to connect to remote systems using PowerShell Remoting. We will cover the basics of remoting, including the different types of remoting, how to enable remoting on a computer, and how to connect to a remote computer.
PowerShell Remoting provides two types of remoting:
Both types of remoting allow you to run commands and scripts on remote computers. However, they have different requirements and configuration steps.
Before you can connect to a remote computer, you need to enable PowerShell Remoting on the remote computer. The following sections will explain how to enable remoting on both Windows and Linux computers.
To enable WinRM remoting on a Windows computer, you need to run the following command in an elevated PowerShell session:
Enable-PSRemoting -Force
This command enables WinRM remoting, configures the firewall rules, and starts the WinRM service. If the computer is in a domain environment, you can also use Group Policy to enable remoting on multiple computers.
To enable SSH remoting on a Linux computer, you need to install the OpenSSH server and start the sshd service. The following commands can be used to enable SSH remoting on a Ubuntu Linux computer:
sudo apt update sudo apt install openssh-server sudo systemctl start sshd.service sudo systemctl enable sshd.service
Once SSH remoting is enabled, you can connect to the Linux computer from a Windows computer using PowerShell Remoting.
PowerShell Remoting allows for remote administration of Windows systems through the use of WinRM (Windows Remote Management). This protocol is used to exchange management data between remote machines and local machines. In order to enable WinRM on a remote system, you will need to configure the following settings:
Set-Service cmdlet to start the service and set it to automatic startup:Set-Service -Name WinRM -StartupType Automatic Start-Service -Name WinRM
Enable-PSRemoting cmdlet to enable WinRM on the remote system and configure the necessary firewall rules:Enable-PSRemoting -Force
Once these settings have been configured on the remote system, you can use the Enter-PSSession cmdlet to establish a remote PowerShell session on the remote machine. Here’s an example:
$cred = Get-Credential Enter-PSSession -ComputerName <remote_computer_name> -Credential $cred
This will prompt you for your remote machine credentials, and then establish a remote PowerShell session on the remote machine. From here, you can execute commands on the remote machine just as you would on a local machine.
In addition to WinRM, PowerShell Remoting also supports SSH (Secure Shell) protocol for remote administration of Linux systems. In order to enable SSH on a remote Linux system, you will need to configure the following settings:
sudo apt-get install openssh-server sudo service ssh start
sudo ufw allow ssh
Once these settings have been configured on the remote Linux system, you can use the Enter-PSSession cmdlet with the -SSHTransport parameter to establish a remote PowerShell session on the remote Linux machine. Here’s an example:
$cred = Get-Credential Enter-PSSession -ComputerName <remote_linux_computer_name> -Credential $cred -SSHTransport
This will prompt you for your remote machine credentials, and then establish a remote PowerShell session on the remote Linux machine using the SSH transport. From here, you can execute commands on the remote Linux machine just as you would on a local machine.
WinRM and SSH are both protocols used for remote management, but they have some key differences. WinRM is a proprietary protocol developed by Microsoft and is primarily used for managing Windows-based systems. It uses HTTP or HTTPS for transport and is enabled by default on Windows systems. On the other hand, SSH is an open standard protocol that is widely used across different platforms, including Linux and Unix systems. It uses the SSH protocol for transport and requires manual configuration on Windows systems.
While both protocols are used for remote management, the choice between WinRM and SSH will depend on the type of system being managed and the specific needs of the administrator. If managing Windows-based systems, WinRM is the recommended protocol as it is integrated with PowerShell and offers native support for managing Windows systems. If managing Linux or Unix-based systems, SSH is the more suitable protocol due to its cross-platform support and popularity within the Linux community.
PowerShell Remoting allows you to run commands on remote systems, which can save you a lot of time and effort. There are several ways to run commands remotely, depending on the scenario you’re working with.
To run commands on a single remote system, you can use the Invoke-Command cmdlet. Here’s an example:
Invoke-Command -ComputerName <RemoteComputerName> -ScriptBlock { Get-Process }
This command will connect to the specified remote computer and run the Get-Process cmdlet on that system.
To run commands on multiple remote systems, you can use the Invoke-Command cmdlet with the -ComputerName parameter followed by an array of computer names. Here’s an example:
Invoke-Command -ComputerName <RemoteComputerName1>, <RemoteComputerName2> -ScriptBlock { Get-Process }
This command will connect to both remote computers and run the Get-Process cmdlet on each system.
PowerShell Remoting also supports one-to-many scenarios, where a single PowerShell session can connect to multiple remote systems simultaneously. This is accomplished using the New-PSSession cmdlet to create a new session, followed by the Invoke-Command cmdlet to run commands on the remote systems. Here’s an example:
$s = New-PSSession -ComputerName <RemoteComputerName1>, <RemoteComputerName2>
Invoke-Command -Session $s -ScriptBlock { Get-Process }
This command will create a new PowerShell session that connects to both remote computers, and then run the Get-Process cmdlet on each system.
PowerShell Remoting provides several options for authentication and encryption, which can help you secure your remote connections. Here are some best practices to keep in mind when using PowerShell Remoting:
If you encounter any security issues with PowerShell Remoting, you can use the following troubleshooting steps:
PowerShell Remoting is a powerful tool for managing remote systems. It allows you to run commands on one or more remote systems, as well as connect to those systems using a secure and encrypted connection. By following best practices for security and troubleshooting, you can use PowerShell Remoting to manage your infrastructure with confidence.
The post PowerShell Remoting: Connecting to Remote Systems appeared first on i Love PowerShell.
]]>