I am trying to remotely force a GPUpdate by means of invoke-command as Invoke-GPUpdate is not available to me in my environment. I was messing around with it one day and it executed as expected, but since then I have been unable to get it to work. It may be environment related, but I just wanted to double check what I have is correct, or there are alternatives I am unaware of. I am currently just trying to call CMD for it to run “Gpupdate /force” but it just hangs on a blank line after execution.
& cmd.exe /c "msg * hi"as expected brings up a popup saying hi.
I have tried pretty much every permutation of the below:
& cmd.exe /c 'gpupdate /force'
cmd.exe /c 'gpupdate /force'
cmd.exe 'gpupdate /force'
cmd 'gpupdate /force'
& cmd 'gpupdate /force'Eventually I would like it to be something like this
Invoke-Command -computername $Computer -Credentials $Cred -Scriptblock{& cmd.exe /c 'gpupdate /force'}Am I doing something wrong with the Syntax?
asked Oct 12, 2023 at 16:33
answered Oct 16, 2023 at 13:34
Managing processes in complex Windows environments can be an overwhelming and time-consuming experience. Having to be constantly logging into different machines at different times, hitting the “Ctrl+Alt+Del”, looking for specific processes, and “Ending Tasks” is a long and tedious process.
With PowerShell (PS), you can programmatically find and stop a service. You can use PS’s cmdlets to create scripts to look for and stop a specific service, scripts that kill a process based on specific criteria, auto-startup scripts, or whatever sets your imagination.
In this tutorial, you’ll learn how to locate and kill any process using two different commands available in PowerShell, the TASKKILL and the Stop-Process cmdlet. The advantage of using PowerShell over simple CMD, is that you can create automation routines to close processes.
Table of Contents
- Kill a process using PowerShell
- Why would you want to kill a process?
- Install and Open PowerShell.
- Open the PowerShell Interface.
- Killing a process with TASKKILL
- How to use TASKKILL?
- Forceful (/f) vs Graceful?
- Task Listing.
- Using TASKKILL in PowerShell?
- Killing a Process with PowerShell’s Stop-Process
- TASKKILL vs Stop-Process?
- A Stop-Process Example?
- Conclusion
Kill a Process Using PowerShell
When an application (or service) starts, Windows OS creates a process for the executable file. This process contains the code and the current activity. Additionally, the OS also creates a unique Process Identifier (PID) for that particular process. This PID is a decimal number that can be used for debugging or troubleshooting.
An example is when you open an application such as Chrome or Skype, Windows creates a particular PID for each of those applications. You can use this PID to attach a debugger, monitor it, or kill the process.
Why would you want to kill a process?
The two traditional ways to kill a process are via the Windows Task Manager and the CMD command prompt. The third way, not so common but very efficient, is using PowerShell.
Install and Open PowerShell
PowerShell (PS) is Microsoft’s automation and configuration management framework. It comes with its own command-line shell and scripting language. PS works well with any tool and is optimized to work with structured data (CSV, XML, JSON, etc), and REST APIs.
Microsoft’s PS is open-source and available as a cross-platform. It is available on Windows, Linux, or macOS.
To download, install, or update the latest stable version of PowerShell, visit the GitHub repository: https://github.com/PowerShell/PowerShell/
Now, let’s open the PowerShell Interface.
Press “Windows + R” keys to open the run box, and type “PowerShell”. Clicking “Ok” will open a regular PS interface. But you can also open an interface with elevated permissions, by pressing Ctrl+Shift+Enter.


Although the PS interface looks a lot like Windows Command Prompt (cmd), PS is a more advanced “version” of cmd. As mentioned before PS comes with its own scripting language and command-line shell.
With PowerShell, you can run any cmd command, like ListTask or KillTask.
Killing a process with TASKKILL
Let’s start by defining the TASKKILL utility (taskkill.exe) and how to use it.
TASKKILL is a Microsoft utility that allows you to terminate one or more processes (or tasks). At the basic level, TASKKILL is like clicking the X button on the top-right corner of any Windows application. It will “gracefully” exit the program and will prompt you “whether to save changes” before exiting. However, the TASKKILL utility gives you more flexibility on how you would want to kill a process— you can go gracefully or forcefully.
This utility can be used from the command line with different configuration arguments such as /F, /T, PID, and /IM.

The TASKKILL command syntax is (As shown in the screenshot above):
The useful parameters to kill a process with TASKKILL are:
- /S (System) Define the remote system to connect to.
- /U (Username) Specify the username.
- /P (password) Determines the password for that specific user.
- /PID (Process ID) Specify the ID of the process you want to terminate.
- /IM (Image name) Specify the image name of the process you want to terminate.
- /T (Terminate) Terminate the PID along with any child processes associated with it.
- /F (Forceful) Forcefully terminate the process.
How to use TASKKILL?
Let’s put together a couple of TASKKILL parameters.
taskkill /PID process-number /F
taskkill /IM process-name /F
Forceful (/f) vs Graceful?
As many of us have probably experienced before, the graceful way to exit a program (the “X” on top of a Windows bar) will usually not work, if an application is frozen or buggy.
When you force a process to exit (forceful kill), you are doing the same as Alt+F4 or going to the task manager with Ctrl+Alt+Del and clicking on “End Task”. Without the parameter (/F) is like clicking on the (X) on the top bar of any window.
So, you’ll need to force a program to exit with (/f) in some cases.
Task Listing
You can also filter your search based on some criteria using the “/fi” parameter. For example:
tasklist /fi "imagename eq notepad.exe"
Again, if you want to know more about the Tasklist command, type “tasklist/?” on the command prompt.

Using TASKKILL in PowerShell?
First, as mentioned before, use the TASKLIST command to find the Image Name and its PID:
Find the name of the process and record the PID or image name (i.e., notepad.exe).
In this example, “notepad.exe” is using the PID:13252
- To gracefully kill the notepad process with pid:
taskkill /pid 13252 - To forcefully kill the notepad process with pid:
taskkill /pid 13252 /f - To forcefully kill the notepad process using image name:
taskkill /im notepad.exe /f
Kill a Process with PowerShell’s Stop-Process
The Stop-Process is PowerShell’s own way to kill a process (although they prefer to use the word “Stop” rather than killing!). Stop-Process is a cmdlet that performs similar to the TASKKILL command but gives you a slightly different set of options.
The Syntax for the Stop-Process command is as follows:
- Stop-Process [-id] <Int32[]> [-passThru] [-Force] [WhatIf][-confirm] [<CommonParameters>]
- Stop-Process -name string[] [-passThru] [-Force] [-WhatIf] [-confirm] [<CommonParameters>]
- Stop-Process -inputObject Process[] [-passThru] [-WhatIf] [-Force] [-confirm] [<CommonParameters>]
TASKKILL vs Stop-Process?
PowerShell’s Stop-Process, on the other hand, helps you create an autonomous task with scripting powers. For example, the “-passthru” parameter allows you to return objects from commands, which you can later use for scripting. The Stop-Process also includes two risk mitigation parameters (-WhatIf) and (-Confirm) to avoid the Stop-Process from making dramatic changes to the system.
A Stop-Process Example?
We’ll kill the notepad process forcefully, first by defining its PID, and then by its process name.
Step 1. Find it
Use the “Tasklist” command to see all your processes (or create a filter).

Step 2. Stop the process with its PID:

Optional: You can also stop the process using its name. For example:
- Stop-process -name notepad -Force

- Stop-Process -name CMD -Force
- Stop-process -name putty -Force
- Stop-Process -Name Chrome -Force
To return a process object to the PowerShell console, use the PassThru command. This command is useful for keeping track of process objects. For example, if you want to monitor the newly opened Notepad process.
The below screenshot starts the process with a -PassThru parameter and later stops the same process with a -PassThru. You can store the returned process object into a variable and use it to monitor metrics like CPU or PM, etc.
Conclusion
Buggy or problematic services and applications can be overwhelming. They are time-consuming to manage and can make entire servers slow— or even crash them.
Instead of having to every time restart the entire server, you can kill the specific service that is giving you headaches, and get the server back to normal.
In this tutorial, we went through two ways to kill a process using PowerShell. The TASKKILL is simple and easy to use. You can connect to remote servers and kill processes using its PID or name. The PowerShell’s Stop-Process cmdlet can do the same but goes beyond by allowing you to automate tasks. With Stop-Process, you can create auto-restart scripts that monitor and kill risky processes.
PowerShell Kill Process Command FAQs
Can I use TASKKILL to terminate multiple processes at once?
How can I find the process ID of a process?
You can use the Task Manager to find the process ID of a process. In Task Manager, select the “View” menu, then select “Select Columns,” and then check the “PID (Process Identifier)” check box. Or you can use the command line tool tasklist in the command prompt, which will list the running process with their pid.
What happens when I use the TASKKILL command?
When you use the TASKKILL command, the specified process is terminated and all resources associated with it are freed up.
Can I use TASKKILL to terminate a process that is not responding?
Yes, you can use the /F option with the TASKKILL command to force the termination of a process that is not responding.
| Введение | |
| Set-ExecutionPolicy Unrestricted -Force | |
| Из консоли запустить как администратор | |
| Сеть | |
| Пользователи | |
| Команды | |
| Похожие статьи |
Set-ExecutionPolicy Unrestricted -Force
Вы пробуете выполнить ваш скрипт
Нужно зайти в PowerShell в режиме администратора и выполнить
Set-ExecutionPolicy Unrestricted -Force
И выполните ещё раз
Переключить PowerShell в режим Администратора прямо из обычной консоли
PowerShell можно командой
start-process powershell -verb runas
Установка PowerShell
Может пригодиться для обновления до более свежей версии.
С помощью winget. Сперва рекомендуется проверить доступные версии
winget search Microsoft.PowerShell
winget install –id Microsoft.Powershell –source winget
PowerShell 7 установится не на замену обычному Windows PowerShell, а как дополнительный
софт.
Чтобы зайти в него нужно ввести в поиск PowerShell 7
Проверка версии, обычно не нужна, так как версия показана перед первым приглашением
командной строки. Тем не менее можно выполнить стандартную команду
Конец рекламы от Google. Если в блоке пусто считайте это рекламой
моей телеги
| Открытые порты |
| Открыть порт |
| Get-NetIPConfiguration: информация о сети |
| Разрешить RDP подключения |
| Статус OpenSSH сервера |
| Запустить sshd |
Конец рекламы от Google. Если в блоке пусто считайте это рекламой
моей телеги
| Список пользователей |
| Создать пользователя |
Конец рекламы хостинга Beget, который я всем рекомендую.
| Get-Content -Tail: Посмотреть конец файла (аналог tail) |
| Get-FileHash: Проверить контрольную сумму файла (аналог md5sum) |
| Select-String: Выбрать строку по паттерну (аналог grep) |
| Stop-Process: Остановить процесс (аналог kill) |
| Создать новый файл (аналог touch) |
| Windows | |
| PowerShell | |
| Установка | |
| Alias | |
| Функции | |
| Сеть в PowerShell | |
| Работа с пользователями в PowerShell | |
| Get-Content -Tail: Посмотреть конец файла в PowerShell (аналог tail) | |
| New-Item: Создать новый файл в PowerShell (аналог touch) | |
| Get-FileHash: Проверить контрольную сумму файла в PowerShell (аналог md5sum) | |
| Запросы к REST API на PowerShell |
Конец рекламы от Яндекса. Если в блоке пусто считайте это рекламой
моей телеги
Key Takeaways
- PowerShell scripts are vital for efficient IT management, especially for Group Policy updates.
- The script facilitates remote execution of ‘gpupdate /force’ across multiple systems.
- It ensures immediate and uniform application of Group Policy changes.
- Significantly more efficient than manual updates or waiting for scheduled refreshes.
- Compatible with all Windows versions supporting PowerShell and Group Policy.
- Scalable for use across small to large networks.
- Requires careful implementation to avoid widespread network issues.
- Testing, monitoring feedback, and regular audits are recommended for optimal use.
- Complements NinjaOne’s platform for enhanced IT infrastructure management.
Introduction
In the ever-evolving landscape of IT management, efficiency and precision are paramount. PowerShell scripts, particularly for tasks like updating Group Policy, have emerged as vital tools in the arsenal of IT professionals and Managed Service Providers (MSPs). Their ability to streamline complex processes is critical for maintaining the health and security of IT infrastructures.
Background
The Script:
#Requires -Version 5.1
<#
.SYNOPSIS Initiates a gpupdate. It will perform a gpupdate /force, if the script is executed as the system or if either "Logout All Users" or "Reboot" options are selected.
.DESCRIPTION Initiates a gpupdate. It will perform a gpupdate /force, if the script is executed as the system or if either "Logout All Users" or "Reboot" options are selected.
.EXAMPLE (No Parameters) Computer Policy updated successfully! User Policy updated successfully! ##### Group Policy Result ##### Domain: test.lan Site Name: Default-First-Site-Name Slow Link?: false Computer Account Used: TESTKYLE-WIN10-TEST$ User Account Used: TESTtuser Name Type Enabled IsValid FilterAllowed AccessDenied ---- ---- ------- ------- ------------- ------------ {1ED0F3EF-6E54-4380-8BB3-6683A8D02E59} Computer N/A false false false {31B2F340-016D-11D2-945F-00C04FB984F9} User N/A false false N/A Default Domain Policy Computer true true true false Local Group Policy Computer true true true false Local Group Policy User true true true false Test GPO User true true true N/A
PARAMETER: -Timeout "30" The amount of time in seconds gpupdate should try to update. After that time gpupdate will timeout if no update is received.
PARAMETER: -CustomFieldName "ReplaceMeWithAnyMultilineCustomField" The name of a multiline customfield to store the results in.
PARAMETER: -User "CONTOSOjdoe" The name of a user you'd like to generate a gpresult report with.
PARAMETER: AllUsers When the script is ran as system it will logout all logged in users upon successful gpupdate. If ran as a user it will logout only just that user if required.
.EXAMPLE Computer Policy updated successfully! User Policy updated successfully! ##### Group Policy Result ##### Domain: test.lan Site Name: Default-First-Site-Name Slow Link?: false Computer Account Used: TESTKYLE-WIN10-TEST$ User Account Used: TESTtuser Name Type Enabled IsValid FilterAllowed AccessDenied ---- ---- ------- ------- ------------- ------------ {1ED0F3EF-6E54-4380-8BB3-6683A8D02E59} Computer N/A false false false {31B2F340-016D-11D2-945F-00C04FB984F9} User N/A false false N/A Default Domain Policy Computer true true true false Local Group Policy Computer true true true false Local Group Policy User true true true false Test GPO User true true true N/A WARNING: -LogoutAllUsers was specified. Logging out all users!
PARAMETER: -Reboot Will schedule a reboot for 15 minutes after script completion (if gpupdate was successful).
.EXAMPLE Computer Policy updated successfully! User Policy updated successfully! ##### Group Policy Result ##### Domain: test.lan Site Name: Default-First-Site-Name Slow Link?: false Computer Account Used: TESTKYLE-WIN10-TEST$ User Account Used: TESTtuser Name Type Enabled IsValid FilterAllowed AccessDenied ---- ---- ------- ------- ------------- ------------ {1ED0F3EF-6E54-4380-8BB3-6683A8D02E59} Computer N/A false false false {31B2F340-016D-11D2-945F-00C04FB984F9} User N/A false false N/A Default Domain Policy Computer true true true false Local Group Policy Computer true true true false Local Group Policy User true true true false Test GPO User true true true N/A WARNING: -Reboot was specified. Scheduling a reboot for 06/22/2023 13:24:16!
.OUTPUTS None
.NOTES Minimum OS Architecture Supported: Windows 10, Windows Server 2016 Release Notes: Renamed script and added Script Variable support
By using this script, you indicate your acceptance of the following legal terms as well as our Terms of Use at https://www.ninjaone.com/terms-of-use. Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms. Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party. Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library or website belonging to or under the control of any other software provider. Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations. Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks. Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script. EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).
#>
[CmdletBinding()]
param ( [Parameter()] [String]$CustomFieldName = "groupPolicy", [Parameter()] [Int]$Timeout = 120, [Parameter()] [String]$User, [Parameter()] [Switch]$Reboot = [System.Convert]::ToBoolean($env:reboot), [Parameter()] [Switch]$LogoutAllUsers = [System.Convert]::ToBoolean($env:logoutAllUsers)
)
begin { # If script variables are used overwrite their parameter if ($env:customFieldName -and $env:customFieldName -notlike "null") { $CustomFieldName = $env:customFieldName } if ($env:groupPolicyTimeout -and $env:groupPolicyTimeout -notlike "null") { $Timeout = $env:groupPolicyTimeout } if ($env:user -and $env:user -notlike "null") { $User = $env:user } # Checks if script is running with elevated permissions function Test-IsElevated { $id = [System.Security.Principal.WindowsIdentity]::GetCurrent() $p = New-Object System.Security.Principal.WindowsPrincipal($id) $p.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator) } # Checks if script is running as system function Test-IsSystem { $id = [System.Security.Principal.WindowsIdentity]::GetCurrent() return $id.Name -like "NT AUTHORITY*" -or $id.IsSystem } # Check if the computer is domain joined (group policy is still a thing on non-domain joined machine just not normally used) function Test-IsDomainJoined { return $(Get-CimInstance -Class Win32_ComputerSystem).PartOfDomain } # Check if its a domain controller running this function Test-IsDomainController { return $(Get-CimInstance -ClassName Win32_OperatingSystem).ProductType -eq 2 } # Outputs the currently logged in users in a more powershell friendly format function Get-QUser { $quser = quser.exe $quser -replace 's{2,}', ',' -replace '>' | ConvertFrom-Csv } # Simply checks if gpupdate threw any errors function Test-GroupPolicyResults { param( [string]$Type, [string]$Result ) if ($Result | Select-String "errors") { Write-Error "[Error] $Type Policy was not updated successfully!" $False } else { Write-Host "$Type Policy updated successfully!" $True } }
}
process { # We don't want to exit the script for most errors as the gpresult report might still be helpful $Success = $True if (-not (Test-IsElevated)) { Write-Warning "This script is not running with Administrator priveledges. The end report will not contain Computer GPO data." if ($User) { Write-Warning "Not elevated unable to create group policy result report for specified user. Will create a report for the current user instead." } } # Warns the end user if the computer is not-domain joined. I don't consider this a failure though just something to keep in mind. if (-not (Test-IsDomainJoined)) { Write-Warning "This computer is not joined to the domain!" } # If a secure connection to the domain cannot be established group policy will fail to update. if ((Test-IsDomainJoined) -and -not (Test-IsDomainController) -and -not (Test-ComputerSecureChannel -ErrorAction Ignore)) { Write-Warning "This device does not have a secure connection to the Domain Controller! Is the domain controller reachable?" $Success = $False } # Updates group policy. We only use /force when Logoff is specified due to gpupdate stalling the script if a logoff is needed. $gpupdate = if (-not (Test-IsSystem) -and $LogoutAllUsers) { Invoke-Command { gpupdate.exe /force /Logoff /wait:$Timeout } } elseif ((Test-IsSystem)) { Invoke-Command { gpupdate.exe /force /wait:$Timeout } } else { Invoke-Command { gpupdate.exe /wait:$Timeout } } # Split up the results between Computer Policy and User Policy $computerResult = $gpupdate | Select-String "Computer Policy" $userResult = $gpupdate | Select-String "User Policy" # Testing them to confirm gpupdate worked $ComputerTest = Test-GroupPolicyResults -Type "Computer" -Result $computerResult $UserTest = Test-GroupPolicyResults -Type "User" -Result $userResult # If either of them are unsuccessful we'll want to exit with a status code of 1 but we'll want the result report first. if (-not $UserTest -or -not $ComputerTest) { $Success = $False } # If the script somehow got interupted before it had a chance to clean up its results we'll want to remove the previous results if (Test-Path "$env:TEMPgpresult.xml" -ErrorAction Ignore) { Remove-Item "$env:TEMPgpresult.xml" -Force } # We can't generate results with gpresult as the SYSTEM user so we'll attempt to generate results for the last logged in user. if ((Test-IsSystem) -and -not $User) { $LastLoggedInUser = Get-ItemPropertyValue -Path "Registry::HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionAuthenticationLogonUI" -Name "LastLoggedOnUser" -ErrorAction Ignore if ($LastLoggedInUser) { Invoke-Command { gpresult.exe /USER $LastLoggedInUser /X "$env:TEMPgpresult.xml" } } else { Write-Error "[Error] Couldn't determine the last logged on user. We cannot generate a report as System please either specify a user using -User or have one sign in. :)" } } elseif ($User -and (Test-IsElevated)) { # Of course if we were given a user to generate results for we'll want to do that instead. Invoke-Command { gpresult.exe /USER $User /X "$env:TEMPgpresult.xml" } } else { # All other cases we'll want to generate the results as the same user the script is running as. Invoke-Command { gpresult.exe /X "$env:TEMPgpresult.xml" } } # If we failed to generate the results that's not a big deal but we'll want to alert whoever ran it that that's what happened. if (-not (Test-Path "$env:TEMPgpresult.xml" -ErrorAction Ignore) ) { Write-Error "Failed to generate report with gpresult!" exit 0 } # Cast the xml to an xml type [xml]$resultXML = Get-Content "$env:TEMPgpresult.xml" # Cleaning up after ourself if (Test-Path "$env:TEMPgpresult.xml" -ErrorAction Ignore) { Remove-Item "$env:TEMPgpresult.xml" -Force } # Lets construct an object for the active gpo's that we can format into a table later $GPOs = $resultXML.DocumentElement | ForEach-Object { ForEach ($GPO in $_.ComputerResults.GPO.Name) { $ComputerGPO = [PSCustomObject]@{ Name = $GPO Type = "Computer" Enabled = $resultXML.DocumentElement.ComputerResults.GPO | Where-Object { $_.Name -like $GPO } | Select-Object Enabled -ExpandProperty Enabled -ErrorAction Ignore IsValid = $resultXML.DocumentElement.ComputerResults.GPO | Where-Object { $_.Name -like $GPO } | Select-Object IsValid -ExpandProperty IsValid -ErrorAction Ignore FilterAllowed = $resultXML.DocumentElement.ComputerResults.GPO | Where-Object { $_.Name -like $GPO } | Select-Object FilterAllowed -ExpandProperty FilterAllowed -ErrorAction Ignore } # If any values are blank we'll want to replace it with N/A if (-not $ComputerGPO.Enabled) { $ComputerGPO.Enabled = "N/A" } if (-not $ComputerGPO.IsValid) { $ComputerGPO.IsValid = "N/A" } if (-not $ComputerGPO.FilterAllowed) { $ComputerGPO.FilterAllowed = "N/A" } $ComputerGPO } ForEach ($GPO in $_.UserResults.GPO.Name) { $UserGPO = [PSCustomObject]@{ Name = $GPO Type = "User" Enabled = $resultXML.DocumentElement.UserResults.GPO | Where-Object { $_.Name -like $GPO } | Select-Object Enabled -ExpandProperty Enabled -ErrorAction Ignore IsValid = $resultXML.DocumentElement.UserResults.GPO | Where-Object { $_.Name -like $GPO } | Select-Object IsValid -ExpandProperty IsValid -ErrorAction Ignore FilterAllowed = $resultXML.DocumentElement.UserResults.GPO | Where-Object { $_.Name -like $GPO } | Select-Object FilterAllowed -ExpandProperty FilterAllowed -ErrorAction Ignore } # If any values are blank we'll want to replace it with N/A if (-not $UserGPO.Enabled) { $UserGPO.Enabled = "N/A" } if (-not $UserGPO.IsValid) { $UserGPO.IsValid = "N/A" } if (-not $UserGPO.FilterAllowed) { $UserGPO.FilterAllowed = "N/A" } $UserGPO } } # Construct report $Report = New-Object System.Collections.Generic.List[string] $Report.Add("`n##### Group Policy Result #####") $Report.Add("`n`nDomain: $($resultXML.DocumentElement.UserResults.Domain)") $Report.Add("`nSite Name: $($resultXML.DocumentElement.UserResults.Site)") $Report.Add("`nSlow Link?: $($resultXML.DocumentElement.UserResults.SlowLink)") $Report.Add("`n`nComputer Account Used: $($resultXML.DocumentElement.ComputerResults.Name)") $Report.Add("`nUser Account Used: $($resultXML.DocumentElement.UserResults.Name)") $Report.Add("`n$($GPOs | Sort-Object -Property Name | Format-Table | Out-String)") # Output Report Write-Host $Report if ($CustomFieldName) { Ninja-Property-Set -Name $CustomFieldName -Value $Report } # If we had any kind of failures its best to not reboot the system or logoff any users if (-not $Success) { exit 1 } elseif ($LogoutAllUsers -and (Test-IsSystem)) { Write-Warning "-LogoutAllUsers was specified. Logging out all users!" (Get-QUser).ID | ForEach-Object { Invoke-Command { logoff.exe $_ } } } elseif ($Reboot) { $RebootTime = (Get-Date).AddMinutes(15) Write-Warning "-Reboot was specified. Scheduling a reboot for $RebootTime!" Invoke-Command { shutdown.exe /r /t 900 } }
}
end {
}Access 300+ scripts in the NinjaOne Dojo
Detailed Breakdown
The script operates on a simple yet powerful premise. Here’s a step-by-step guide to its functionality:
- Initiating PowerShell Session: The script starts by creating a remote PowerShell session to the target machine. This step is crucial for executing commands remotely.
- Executing ‘gpupdate’: Once the session is established, the script runs ‘gpupdate /force’. This command enforces an immediate refresh of Group Policy settings, ensuring that any recent changes are applied.
- Verification and Feedback: After executing the command, the script verifies its success and provides feedback. This feedback is essential for IT admins to know the status of the policy update.
Potential Use Cases
Comparisons
Traditional methods involve manually updating each machine or waiting for the scheduled Group Policy refresh. This script’s approach significantly reduces time and effort, eliminating the need for manual intervention and reducing the window of vulnerability.
FAQs
- Is this script compatible with all Windows versions?
Yes, it works with all Windows versions that support PowerShell and Group Policy. - How does this differ from scheduled Group Policy updates?
This script forces an immediate update, unlike scheduled updates which follow a set interval. - Can it be used on a large network?
Absolutely, it’s scalable and effective for networks of any size.
Implications
While the script enhances efficiency, it also emphasizes the need for responsible Group Policy management. Incorrect usage can lead to widespread issues across the network. Hence, understanding the impact of policy changes is crucial before deployment.
Recommendations
- Test Before Deployment: Always test the script in a controlled environment before full-scale deployment.
- Monitor Feedback: Pay attention to the feedback provided by the script post-execution to catch any potential issues early.
- Regular Audits: Conduct regular policy audits to ensure ongoing relevance and effectiveness.
Final Thoughts
I recently used PowerShell to build an app for generating strong, random passwords based on selectable criteria. After writing my GUI-based password generator, I began to wonder about the possibility of using PowerShell to do the opposite – crack passwords.
As I pondered the idea, I contemplated which type of password I should try to crack, given the variety of different passwords available. Ultimately, I decided to try my luck with a I had long been locked out of due to forgetting the password.
After extensive trial and error, I was indeed able to use PowerShell to crack the password for the aforementioned file. However, as I prepared to write this article about the experiment, I asked myself whether it would be irresponsible of me to publish a tool designed to defeat a password prompt. Ultimately, I decided to publish a modified version of my script. After all, a PowerShell brute-force password cracker could serve legitimate purposes in penetration testing. The modification that I made involved removing certain code segments from the script to limit its functionality.
This modified script could be thought of as a do-it-yourself penetration testing tool, providing the basic structure for brute-force password cracking. I have stopped short of publicly releasing a tool that can crack passwords without being modified.
PowerShell Script for Brute-Force Password Cracking
With that all said, here is my script:
How the PowerShell Script Works
Let’s look at how this script works.
1. The script body begins by defining several character sets, including $UpperCase, $LowerCase, $Numbers, and $Symbols. These sets determine the characters that will be used in password-guessing attempts. The lines of code are directly copied from my GUI password generator script but can be adjusted to include additional characters if necessary.
3. Next, a line of code sets $MaxDepth to 8. The $MaxDepth variable defines the maximum password length. For right now, with $MaxDepth set to 8, the script will attempt password guesses of up to 8 characters in length. You can change this number to adjust the maximum password length.
4. The subsequent lines of code use a For statement and a couple of ForEach statements to cycle through all possible passwords. The current password guess is stored in a variable called $NewCombination, while the $Password variable also stores the current password guess.
5. Just after the $Password variable is defined, you will notice a line:
$ErrorOccurred = Test-Password -Password $PasswordThis line of code passes the current password guess to a function called Test-Password. The function returns a variable called $ErrorOccurred, which will either be assigned a value of $True or $False.
The function itself is relatively simple. It initially sets $ErrorOccurred to $False. Incidentally, if you just want to see the script cycling through all possible password combinations on screen without actually cracking a password, you can change the initial value of $ErrorOccurred to $True. You can see what the script does after such a modification in Figure 1.

Figure 1. This is what happens if you change $False to $True.
6. Once $ErrorOccurred is set, you will notice a . This is where you would insert the code to attempt submitting the current password guess to see if it is valid. The approach here is that if the password guess fails (because the password is incorrect), PowerShell will return an error. This triggers the Catch section to execute, setting $ErrorOccurred to $True before returning to the script’s main body. Otherwise, if no error occurs, the password is presumed correct, leaving $ErrorOccurred as $False.
Before moving forward, I will give you one more hint about making this script work as an actual brute-force cracking tool. To make the script work as intended, I had to append -ErrorAction Stop to the end of the line of code that submits the password guess to the file I aimed to crack. This addition ensures that the code within the Catch section is executing.
7. Once PowerShell returns to the script’s main body, there is a simple check to see if $ErrorOccurred is set to $True or $False. If $ErrorOccurred is true, the current password guess was rejected, meaning that the password is incorrect. Conversely, if ErrorOccurred is false, the password was accepted, meaning that the password is correct. At that point, the script should display the new password and terminate.
It is worth noting that when I actually used this script to crack a password, the did not terminate the script. That meant that I had to remove the “Password Not Found” line just so that I could see which password was ultimately accepted. However, I believe that this anomaly had more to do with the type of password being cracked and the approach taken, rather than an issue with the script itself.
About the Author(s)

Brien Posey is a bestselling technology author, a speaker, and a 20X Microsoft MVP. In addition to his ongoing work in IT, Posey has spent the last several years training as a commercial astronaut candidate in preparation to fly on a mission to study polar mesospheric clouds from space.
A. A way of forcing (one time only, not system wide) a tool to open in cmd when Windows Terminal is set as default?
B. A way to force Windows Terminal (one time only, not system wide) to not show tabs?
2 gold badges9 silver badges18 bronze badges
B. Nope. That’s not something that’s possible today, nor do I believe it’s something on the issue tracker currently.
1 silver badge4 bronze badges
I gave zadjii the points since using conhost.exe is the correct answer. But I ended up using ConEmu which has a lot more features for automating a terminal window https://conemu.github.io/
2 gold badges9 silver badges18 bronze badges



