10 Commands to Administer Windows with PowerShell
Table of Contents
- I. Introduction
- II. Retrieving Information About the Computer
- III. Restarting the Local or Remote Computer
- IV. Renaming the Computer
- V. Integrating the Computer into Active Directory
- VI. Installing a Role or Feature
- VII. Managing Windows Processes
- VIII. Stopping a Windows Process
- IX. History of Installed Updates
- X. Searching for Large Files
- XI. Consulting Windows Event Logs
- XII. Conclusion
I. Introduction
In this chapter, we will explore PowerShell commands that are useful for administering Windows workstations and Windows Server, using 10 practical cases as examples! This list is not exhaustive, and we will continue to manipulate other cmdlets in the upcoming chapters.
II. Retrieving Information About the Computer
The βGet-ComputerInfoβ cmdlet can be used to retrieve general information about the local computer. It will return diverse information about the operating system, hardware, regional settings, system parameters, and even the BIOS. It can be very useful in many situations.
Get-ComputerInfo
Here's an example of the result:

For example, the βOsNameβ property will return the full name of the operating system (βMicrosoft Windows 11 Professionalβ) while the βOsBuildNumberβ property will return the build number (β22631β).
In fact, this is a cmdlet that consolidates information we can obtain through WMI classes, except here, we don't need to know the corresponding WMI queries. This avoids using the βGet-WmiObjectβ and βGet-CimInstanceβ cmdlets.
III. Restarting the Local or Remote Computer
If you want to restart a computer using PowerShell from the command line, you can use the "shutdown" command with the right options, but also the PowerShell cmdlet "Restart-Computer". It is compatible only with Windows, and we can use it to restart the local machine or remote machines.
Executing it on a local machine, without specifying any parameters, will trigger an immediate restart of the machine.
Restart-Computer
It is very useful for restarting multiple remote machines, which will avoid connecting and opening a session on the machines in question to initiate a restart. This implies that remote management is enabled on the remote machine and that you have sufficient permissions (otherwise, you must use the β-Credentialβ parameter).
The example below allows restarting the host βSRV-ADDS-01.it-connect.localβ.
Restart-Computer -ComputerName SRV-ADDS-01.it-connect.local
We can also use the βRestart-Computerβ cmdlet in a script and instruct PowerShell to wait for the machine to restart before continuing the script execution. For this, we need to use additional parameters.
The example below allows restarting the host βSRV-ADDS-01.it-connect.localβ, then we will wait for the restart for 3 minutes (timeout of 180 seconds), while checking every 3 seconds if the machine is back online. The β-Forceβ parameter is useful to force the restart, even if there is a user logged on to the machine.
Restart-Computer -ComputerName SRV-ADDS-01.it-connect.local -Wait -Timeout 180 -Delay 3 -Force

IV. Renaming the Computer
After installing a new Windows machine, you can rename the system using the βRename-Computerβ cmdlet. The β-NewNameβ parameter allows you to specify the new hostname, while the β-Restartβ parameter will allow you to restart the machine immediately to finalize the operation.
Here's an example to assign the name βPC-W11β to the local machine.
Rename-Computer -NewName "PC-W11" -Restart
We can also act on a remote machine using the β-ComputerNameβ parameter.
V. Integrating the Computer into Active Directory
To integrate a Windows machine into an Active Directory directory, we can navigate through the Windows graphical interface, or use the PowerShell cmdlet named "Add-Computer". The advantage is that it's used the same way on Windows 10, Windows 11, Windows Server, etc... So, we won't waste time navigating through Windows menus that vary from one version to another.
The example below allows integrating the domain βit-connect.localβ and we will be prompted to provide credentials to authenticate with Active Directory directory services. The βGet-Credentialβ cmdlet is used to ask the user to enter credentials (a username and password), and the information entered will be used as the value for the β-DomainCredentialβ parameter.
Add-Computer -DomainName "it-connect.local" -DomainCredential (Get-Credential)
VI. Installing a Role or Feature
On a Windows workstation, we can install additional features by selecting from a list of optional features. On a Windows Server, we can also install roles and features: DHCP server, DNS server, WSUS, Active Directory Domain Services, etc.
Therefore, depending on the type of operating system, we must not use the same cmdlet to install or uninstall features or roles:
- Install-WindowsFeature on Windows Server
- Enable-WindowsOptionalFeature on Windows
These cmdlets must be used from a PowerShell console opened as an administrator.
A. Servers Running Windows Server
Before even trying to install a Windows Server feature or role, we will generate a list to indicate the status of each item.
Get-WindowsFeature
Here is an example of output where we can see that the roles βDHCP Serverβ and βDNS Serverβ are installed.

If we want to obtain a precise list of all roles and features installed on a server, we can filter like this:
Get-WindowsFeature | Where-Object { $_.InstallState -eq "Installed" }
Then, to proceed with the installation, we must use the βInstall-WindowsFeatureβ cmdlet. This cmdlet can install one or more features at a time, and it can also act on a remote machine.
The following example installs the βHyper-Vβ role on the server, including the management tools (β-IncludeManagementToolsβ), which means the βHyper-V Managerβ as part of this role installation. The server will also restart automatically (β-Restartβ).
Install-WindowsFeature -Name Hyper-V -IncludeManagementTools -Restart
The reverse operation, namely uninstalling a feature or role, is possible using the βUninstall-WindowsFeatureβ cmdlet.
B. Windows Workstations
Now, we will discuss managing optional features on Windows workstations.
We can list all available optional features using the βGet-WindowsOptionalFeatureβ cmdlet. Specifying the β-Onlineβ parameter means we are targeting the online Windows image, which is the one running on the current machine.
Get-WindowsOptionalFeature -Online | Format-Table FeatureName, State
This will provide a table with the name of all features and their status. If the βStateβ property contains βEnabledβ, it means the feature is activated, and therefore installed, on the local machine.

Then, we can install a feature using the βEnable-WindowsOptionalFeatureβ cmdlet. For example, to install the Hyper-V role on Windows 10 or Windows 11, we should use the following command:
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All
This will install the Hyper-V role on Windows, along with any potential dependencies.
VII. Managing Windows Processes
The PowerShell βGet-Processβ cmdlet allows listing active processes on a machine. It will provide numerous pieces of information about them, including their name, PID, consumed memory, consumed CPU, the date and time when the process was created, etc.
Get-Process
Without using PowerShell, we can use the Windows βTask Managerβ to get a real-time overview of processes running on the local machine.

The βGet-Processβ cmdlet will allow doing the same thing using PowerShell. Running it without parameters will list the active processes at time t:

In the output above, it's interesting to note that the property names (columns) are actually aliases of properties to other property names. The βGet-Memberβ command we studied in a previous chapter allows us to verify this:
Get-Process | Get-Member Name MemberType Definition ---- ---------- ---------- Handles AliasProperty Handles = Handlecount Name AliasProperty Name = ProcessName NPM AliasProperty NPM = NonpagedSystemMemorySize64 PM AliasProperty PM = PagedMemorySize64 SI AliasProperty SI = SessionId VM AliasProperty VM = VirtualMemorySize64 WS AliasProperty WS = WorkingSet64
To get an output that closely resembles the display of the βTask Managerβ, and specifically to have the name of the user who initiated the process execution, we will add the parameter β-IncludeUserNameβ.
Get-Process -IncludeUserName

The property named βWSβ corresponds to ββWorkingSet, which actually indicates the RAM consumption of this process, here in βMegabytesβ. While the βCPUβ column indicates the processor usage time.
With the initial command (without β-IncludeUserNameβ), the value is in bytes. Thus, to get the list of all processes that consume at least 100 MB of RAM, we will use the value β100000000β.
Get-Process | Where-Object { $_.WorkingSet -ge 100000000 }
If we are looking for a specific running process related to a software, for example, the Chrome browser and its process βchromeβ, we can refine the command:
Get-Process -Name βchromeβ -IncludeUserName
Or, simply:
Get-Process -Name βchromeβ
The list of properties available with the βGet-Processβ command is very long. We can, for example, get the creation date of each process using the βStartTimeβ property.
Get-Process | Format-Table Name, StartTime

VIII. Stopping a Windows Process
In addition to the βGet-Processβ cmdlet, the one named βStop-Processβ plays a key role in process management, as it will allow us to stop a process. This can be very useful for attempting to force quit a program that you can't stop properly.
We will try to stop all processes associated with the βMicrosoft Edgeβ browser. We can list these processes with the βGet-Processβ cmdlet:
Get-Process "msedge"
Then, we can send the list of processes to βStop-Processβ via the pipeline. This will immediately kill all processes, so this command is powerful but can also be dangerous.
Get-Process "msedge" | Stop-Process
We can see that all βmsedgeβ processes have been stopped:

If you want to stop only a process with a specific ID, it's possible. In this case, we must use the parameter β-Idβ followed by the ID of the process to stop. For example:
Stop-Process -Id 652
To identify your target, first work with βGet-Processβ then initiate βStop-Processβ. You can even store the result in a variable and then call it with βStop-Processβ.
IX. History of Installed Updates
Tracking Windows updates is very important. On this operating system, the βWindows Updateβ component is responsible for searching and installing updates.
PowerShell offers a cmdlet named βGet-HotFixβ that allows you to get the list of hotfixes installed on the local machine, relying on the WMI βWin32_QuickFixEngineeringβ class. We can use it this way to get a list of hotfixes, sorted by installation date (from newest to oldest):
Get-HotFix | Sort-Object -Property InstalledOn -Descending
Here's an example:

The problem is that this history does not contain the list of all installed updates, so it doesn't provide a complete overview of the update history.
To get more accurate results, we will install the βPSWindowsUpdateβ module on our machine. This community module is available on the PowerShell Gallery website.
Install-Module -Name PSWindowsUpdate -Force
This module works with Windows PowerShell and PowerShell, including PowerShell 7. Once the installation is complete, we can list the available commands in this module:
Get-Command -Module PSWindowsUpdate
This module allows for comprehensive management of Windows Update. It is very complete and not limited to obtaining the list of installed updates.
The example below will obtain the list of all installed updates, from the most recent to the oldest. It also includes definition updates for Microsoft Defender, those for PowerShell (for PowerShell 7, if updates through Windows Update are enabled), etc.
Get-WUHistory | Sort-Object -Property Date -Descending
Here's an example:

We can improve this display by selecting three properties: βKBβ to have the KB number of the update, βDateβ to have the date and time of installation, and βTitleβ to have the full title of the update. We can also use a graphical display mode via βOut-GridViewβ, although this is optional. We only display updates where the βKBβ column is not empty.
Get-WUHistory | Select-Object KB, Date, Title | Where-Object { $_.KB -ne "" }
Get-WUHistory | Select-Object KB, Date, Title | Where-Object { $_.KB -ne "" } | Out-GridView
The result obtained is much more interesting than with the βGet-HotFixβ cmdlet.

We can also display all updates installed from a certain date, thanks to the β-MaxDateβ parameter. To get the updates installed in the last 31 days, it looks like this:
Get-WUHistory -MaxDate $((Get-Date).AddDays(-31))
While for updates installed since March 1, 2024, it looks like this:
Get-WUHistory -MaxDate "01/03/2024"
Finally, you can search for a specific update by its KB name. Here's an example to search for the update βKB5035853β.
Get-WUHistory | Where-Object { $_.KB -eq "KB5035853" }
X. Searching for Large Files
The βGet-ChildItemβ cmdlet is used to list the contents of a directory or a complete tree structure as it will return all files and folders present under the specified root. It has access to the properties of folders and files, which opens up many possibilities: performing a search on specific file types (based on extension), performing a search based on file size, etc.
The command below lists the top-level content present in βC:Windowsβ.
Get-ChildItem -Path "C:Windows"
If we want to list all files and folders recursively, we need to add this parameter:
Get-ChildItem -Path "C:Windows" -Recurse
We can refine our search based on a filter using the β-Filterβ parameter. For example, to display only executable files with the β.exeβ extension:
Get-ChildItem -Path "C:Windows" -Recurse -Filter *.exe
Now, we will try to obtain the list of the 10 largest files present on the βP:β volume of a machine, which could be a workstation or a server. We get a ranking of files, from the largest to the smallest. We could have a more substantial list by adjusting the value of the β-Firstβ parameter of the βSelect-Objectβ cmdlet.
Get-ChildItem P: -Recurse | Sort-Object -Descending -Property Length | Select-Object -First 10 Name, Length

To make the size more easily readable, we can create a calculated property based on using the β[math]:round()β method to display the size in GB:
Get-ChildItem P: -Recurse | Sort-Object -Descending -Property Length | Select-Object -First 10 Name, @{Name="GB";Expression={[math]::round($_.Length/1Gb, 3)}}
Here is the result obtained:

Finally, to make it more precise, we can add the βDirectoryNameβ property as it will add the path corresponding to the file location.
Get-ChildItem P: -Recurse | Sort-Object -Descending -Property length | Select-Object -First 10 name, @{Name="MB";Expression={[math]::round($_.Length/1mb, 2)}},DirectoryName
Finally, know that we could also target the search on a specific file type. For example, to get the βTop 10β ZIP archives present on the βP:β volume of the machine, we can adjust the previous command like this:
Get-ChildItem P: -Recurse -Include "*.zip" | Sort-Object -Descending -Property length | Select-Object -First 10 name, @{Name="MB";Expression={[math]::round($_.Length/1mb, 2)}},DirectoryName
XI. Consulting Windows Event Logs
On a Windows machine, logs are accessible through the "βEvent Viewerβ" which contains a set of logs, notably the "Application", "System", and "Security" logs which are the most well-known.
Certain actions performed on the system are likely to create an event. Errors are also visible in the logs. This makes it a very interesting source of information for investigating troubleshooting or security issues, even if sometimes the logs lack details (which may prompt us to use a tool such as βSysmonβ).
PowerShell is capable of interacting with Windows logs, whether it's to create a log, create an event or view existing events. We will focus on the latter point.
There are two cmdlets for viewing Windows logs: βGet-EventLogβ and βGet-WinEventβ. The second is the successor to the first, but both still work, and in some cases, βGet-EventLogβ can be more advantageous.
First, we can list all the logs present on the local machine:
Get-WinEvent -ListLog *
We get a list with several pieces of information, including the name of each log, as well as the number of events it currently contains, and its maximum size in bytes.

This cmdlet is capable of accessing events present in logs under βWindows Logsβ and βApplications and Services Logsβ.

Then, we can use this cmdlet to perform some searches in these logs. Here are some examples.
- List all events in the βSystemβ log
Get-EventLog -LogName "System"
Get-WinEvent -LogName "System"
- List the 10 most recent events from the βSystemβ log
Get-EventLog -LogName "System" -Newest 10
The βGet-WinEventβ cmdlet doesn't have a β-Newestβ parameter, so if we want to get the 10 most recent events, we need to use the β-MaxEventsβ parameter or associate it with βSelect-Objectβ, although the first option is more relevant:
Get-WinEvent -LogName "System" -MaxEvents 10
Get-WinEvent -LogName "System" | Select-Object -First 10
- List the latest errors in the βSystemβ log
Get-EventLog -LogName "System" -EntryType Error
It's important to note that the βGet-EventLogβ cmdlet doesn't have access to logs under βApplications and Services Logsβ, which prevents us from reading certain logs. In this case, we can use βGet-WinEventβ with a filter on the βLevelDisplayNameβ property. But be careful, as the value takes into account the language of the operating system.
Here's how to filter to display only errors:
Get-WinEvent -LogName "System" | Where-Object { $_.LevelDisplayName -eq "Erreur" }
- List events corresponding to a specific ID
If you're looking for all events associated with a specific ID, here's the syntax to use:
Get-EventLog -LogName "System" -InstanceId 107
The example below allows you to search for events with ID β107β in the βSystemβ log.
- Perform a keyword search in a log
The -Message
parameter of the Get-EventLog
cmdlet allows you to perform a search based on the content of the message, that is, the description of the event. This is useful for performing a keyword search.
Here's the syntax:
Get-EventLog -LogName "System" -Message "*<mot clΓ©>*"
It's important to specify the asterisk before and after your keyword (consisting of one or more words) to perform a matching search.
XII. Conclusion
There are many other very interesting cmdlets that respond to other use cases and scenarios, as PowerShell is a very rich language: we will continue to manipulate others in the upcoming chapters.
