Solved: Looking for a PowerShell game or practice exercise to prepare for my exam

Solved: Looking for a PowerShell game or practice exercise to prepare for my exam

Source: Dev.to

🚀 Executive Summary ## 🎯 Key Takeaways ## The PowerShell Exam Prep Conundrum: Symptoms and Solutions ## Symptoms: The Exam Prep Predicament ## Solution 1: Structured Practice Scenarios (The Real-World Simulator) ## How to Implement: ## Example Scenarios and Commands: ## Solution 2: Gamified Learning Platforms (The Interactive Challenge) ## Examples: ## Comparison: PowerShell Koans vs. Hack The Box / TryHackMe ## Solution 3: Scripting Project-Based Learning (The Portfolio Builder) ## How to Implement: ## Example Project: Disk Usage Reporter ## Best Practices for Exam-Focused Practice ## Conclusion TL;DR: Many IT professionals face a gap between theoretical knowledge and practical application when preparing for PowerShell exams, leading to a need for engaging, hands-on practice. This post addresses this by outlining solutions such as structured practice scenarios in lab environments, gamified learning platforms like PowerShell Koans and Hack The Box, and project-based scripting to build real-world skills and confidence. Preparing for a PowerShell exam demands more than just theoretical knowledge; it requires hands-on practical application. This post details structured practice scenarios, gamified learning platforms, and project-based approaches to solidify your skills and boost exam confidence. Many IT professionals, when facing a PowerShell certification exam, find themselves in a familiar bind. The official documentation and study guides are invaluable for understanding cmdlets and concepts, but they often fall short in providing the kind of practical, engaging exercises that truly build muscle memory and problem-solving skills. The Reddit thread title, “Looking for a PowerShell game or practice exercise to prepare for my exam,” perfectly encapsulates this common challenge. The core symptoms typically include: To bridge this gap and turn theoretical knowledge into actionable expertise, we need diverse and practical approaches to PowerShell practice. This approach focuses on simulating common IT administration tasks. The goal is to break down complex problems into manageable PowerShell cmdlets and scripts, mirroring the kind of challenges you’d encounter in a production environment or on an exam. User Account Management (Active Directory or Local): File System Operations: Gamified platforms offer an engaging, often competitive, way to learn and practice PowerShell by framing exercises as puzzles, challenges, or CTF (Capture The Flag) style scenarios. These are excellent for developing problem-solving skills under timed or objective-driven conditions. PowerShell Koans is a fantastic, self-guided test suite inspired by Ruby Koans. It’s designed to teach you PowerShell by having you fix failing tests. You clone a Git repository, run a script, and then fill in missing values or correct expressions in specific files until all tests pass. You’ll then open files like About\_Asserts.Koans.ps1 or About\_Variables.Koans.ps1 and find lines similar to this: You replace "" with the correct value (e.g., 2) and re-run .\PowerShell.Koans.ps1 until that test passes, moving on to the next failing test. This hands-on, iterative process solidifies your understanding of core PowerShell concepts, operators, and cmdlets. While primarily focused on cybersecurity, platforms like Hack The Box and TryHackMe offer “rooms” or “paths” that heavily leverage PowerShell for Windows administration, reconnaissance, and post-exploitation. Engaging with these can significantly enhance your practical scripting and command-line prowess in a realistic, networked environment. Instead of isolated exercises, embark on building a complete script or tool to solve a recurring problem. This integrates multiple PowerShell concepts, forces you to think about script structure, error handling, parameterization, and output formatting. It’s the ultimate way to simulate real-world demands and build a portfolio of usable scripts. Objective: Create a PowerShell script that scans specified directories (local or network shares) and generates a report of large files and folders, optionally filtering by age or file type. Key PowerShell Concepts Involved: Basic Structure Example (Conceptual): Preparing for a PowerShell exam is a journey that benefits immensely from a multi-faceted approach to practice. By integrating structured, real-world scenarios, leveraging engaging gamified platforms, and tackling ambitious project-based scripting, you can transform theoretical knowledge into practical expertise. Each method reinforces different aspects of your PowerShell proficiency, collectively building the confidence and skill set required not only to pass your exam but also to excel as a DevOps engineer or IT professional. Choose the methods that resonate most with your learning style, but don’t be afraid to mix and match. The more diverse your practice, the more prepared you’ll be for whatever challenges your exam — or your daily job — throws your way. 👉 Read the original article on TechResolve.blog Templates let you quickly answer FAQs or store snippets for re-use. Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment's permalink. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse COMMAND_BLOCK: # For Active Directory (requires RSAT-AD-PowerShell) New-ADUser -Name "John Doe" -SamAccountName "jdoe" -UserPrincipalName "[email protected]" -Department "IT" -DisplayName "John Doe" -Enabled $true -AccountPassword (Read-Host -AsSecureString "Set password for jdoe") Add-ADGroupMember -Identity "IT Admins" -Members "jdoe" # For Local User $Password = ConvertTo-SecureString "P@ssword123!" -AsPlainText -Force New-LocalUser -Name "testuser" -Password $Password -PasswordNeverExpires $true -UserCannotChangePassword $true Add-LocalGroupMember -Group "Administrators" -Member "testuser" COMMAND_BLOCK: # For Active Directory (requires RSAT-AD-PowerShell) New-ADUser -Name "John Doe" -SamAccountName "jdoe" -UserPrincipalName "[email protected]" -Department "IT" -DisplayName "John Doe" -Enabled $true -AccountPassword (Read-Host -AsSecureString "Set password for jdoe") Add-ADGroupMember -Identity "IT Admins" -Members "jdoe" # For Local User $Password = ConvertTo-SecureString "P@ssword123!" -AsPlainText -Force New-LocalUser -Name "testuser" -Password $Password -PasswordNeverExpires $true -UserCannotChangePassword $true Add-LocalGroupMember -Group "Administrators" -Member "testuser" COMMAND_BLOCK: # For Active Directory $CutoffDate = (Get-Date).AddDays(-90) Get-ADUser -Filter {Enabled -eq $false -or LastLogonDate -lt $CutoffDate} -Properties LastLogonDate | Select-Object Name, SamAccountName, LastLogonDate, Enabled COMMAND_BLOCK: # For Active Directory $CutoffDate = (Get-Date).AddDays(-90) Get-ADUser -Filter {Enabled -eq $false -or LastLogonDate -lt $CutoffDate} -Properties LastLogonDate | Select-Object Name, SamAccountName, LastLogonDate, Enabled CODE_BLOCK: Stop-Service -Name "BITS" -PassThru -Force Set-Service -Name "BITS" -StartupType Automatic CODE_BLOCK: Stop-Service -Name "BITS" -PassThru -Force Set-Service -Name "BITS" -StartupType Automatic CODE_BLOCK: Get-Service | Where-Object {$_.StartName -eq "LocalSystem"} | Select-Object DisplayName, Name, StartName CODE_BLOCK: Get-Service | Where-Object {$_.StartName -eq "LocalSystem"} | Select-Object DisplayName, Name, StartName CODE_BLOCK: Get-ChildItem -Path "C:\Data" -Recurse -File | Where-Object {$_.Length -gt 1GB} | Select-Object FullName, Length CODE_BLOCK: Get-ChildItem -Path "C:\Data" -Recurse -File | Where-Object {$_.Length -gt 1GB} | Select-Object FullName, Length CODE_BLOCK: $Path = "C:\SensitiveData" $ACL = Get-Acl $Path $AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("IT_Users", "Read", "ContainerInherit,ObjectInherit", "None", "Allow") $ACL.AddAccessRule($AccessRule) Set-Acl $Path $ACL CODE_BLOCK: $Path = "C:\SensitiveData" $ACL = Get-Acl $Path $AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("IT_Users", "Read", "ContainerInherit,ObjectInherit", "None", "Allow") $ACL.AddAccessRule($AccessRule) Set-Acl $Path $ACL COMMAND_BLOCK: # 1. Clone the repository git clone https://github.com/mattcomic/PowerShell-Koans.git cd PowerShell-Koans # 2. Run the Koans script .\PowerShell.Koans.ps1 Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: # 1. Clone the repository git clone https://github.com/mattcomic/PowerShell-Koans.git cd PowerShell-Koans # 2. Run the Koans script .\PowerShell.Koans.ps1 COMMAND_BLOCK: # 1. Clone the repository git clone https://github.com/mattcomic/PowerShell-Koans.git cd PowerShell-Koans # 2. Run the Koans script .\PowerShell.Koans.ps1 COMMAND_BLOCK: # Fill in the blanks to make this test pass It "can evaluate simple expressions" { (1 + 1) | Should-Be } Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: # Fill in the blanks to make this test pass It "can evaluate simple expressions" { (1 + 1) | Should-Be } COMMAND_BLOCK: # Fill in the blanks to make this test pass It "can evaluate simple expressions" { (1 + 1) | Should-Be } COMMAND_BLOCK: function Get-DiskUsageReport { [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [string[]]$Path, [long]$MinFileSizeKB = 1024, # Default to 1MB [int]$MinAgeDays = 0, # Default to no age filter [string[]]$ExcludeExtension # e.g., @(".tmp", ".log") ) begin { $Report = @() } process { foreach ($p in $Path) { Write-Verbose "Scanning path: $p" try { $items = Get-ChildItem -Path $p -Recurse -ErrorAction Stop | Where-Object { # Filter for files larger than MinFileSizeKB ($_.PSIsContainer -eq $false -and $_.Length / 1KB -gt $MinFileSizeKB) -or # Include directories always, we'll sum their content later $_.PSIsContainer } foreach ($item in $items) { if ($item.PSIsContainer) { # Calculate folder size $folderSize = (Get-ChildItem -Path $item.FullName -Recurse -File -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum / 1MB $Report += [PSCustomObject]@{ Path = $item.FullName Type = "Folder" SizeMB = "{0:N2}" -f $folderSize LastWrite = $item.LastWriteTime } } else { # Process files if ($MinAgeDays -gt 0 -and $item.LastWriteTime -lt (Get-Date).AddDays(-$MinAgeDays)) { # Skip if file is too new and age filter is active continue } if ($ExcludeExtension -contains $item.Extension) { # Skip if extension is excluded continue } $Report += [PSCustomObject]@{ Path = $item.FullName Type = "File" SizeMB = "{0:N2}" -f ($item.Length / 1MB) LastWrite = $item.LastWriteTime } } } } catch { Write-Warning "Could not access path '$p': $($_.Exception.Message)" } } } end { $Report | Sort-Object SizeMB -Descending } } Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: function Get-DiskUsageReport { [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [string[]]$Path, [long]$MinFileSizeKB = 1024, # Default to 1MB [int]$MinAgeDays = 0, # Default to no age filter [string[]]$ExcludeExtension # e.g., @(".tmp", ".log") ) begin { $Report = @() } process { foreach ($p in $Path) { Write-Verbose "Scanning path: $p" try { $items = Get-ChildItem -Path $p -Recurse -ErrorAction Stop | Where-Object { # Filter for files larger than MinFileSizeKB ($_.PSIsContainer -eq $false -and $_.Length / 1KB -gt $MinFileSizeKB) -or # Include directories always, we'll sum their content later $_.PSIsContainer } foreach ($item in $items) { if ($item.PSIsContainer) { # Calculate folder size $folderSize = (Get-ChildItem -Path $item.FullName -Recurse -File -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum / 1MB $Report += [PSCustomObject]@{ Path = $item.FullName Type = "Folder" SizeMB = "{0:N2}" -f $folderSize LastWrite = $item.LastWriteTime } } else { # Process files if ($MinAgeDays -gt 0 -and $item.LastWriteTime -lt (Get-Date).AddDays(-$MinAgeDays)) { # Skip if file is too new and age filter is active continue } if ($ExcludeExtension -contains $item.Extension) { # Skip if extension is excluded continue } $Report += [PSCustomObject]@{ Path = $item.FullName Type = "File" SizeMB = "{0:N2}" -f ($item.Length / 1MB) LastWrite = $item.LastWriteTime } } } } catch { Write-Warning "Could not access path '$p': $($_.Exception.Message)" } } } end { $Report | Sort-Object SizeMB -Descending } } COMMAND_BLOCK: function Get-DiskUsageReport { [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [string[]]$Path, [long]$MinFileSizeKB = 1024, # Default to 1MB [int]$MinAgeDays = 0, # Default to no age filter [string[]]$ExcludeExtension # e.g., @(".tmp", ".log") ) begin { $Report = @() } process { foreach ($p in $Path) { Write-Verbose "Scanning path: $p" try { $items = Get-ChildItem -Path $p -Recurse -ErrorAction Stop | Where-Object { # Filter for files larger than MinFileSizeKB ($_.PSIsContainer -eq $false -and $_.Length / 1KB -gt $MinFileSizeKB) -or # Include directories always, we'll sum their content later $_.PSIsContainer } foreach ($item in $items) { if ($item.PSIsContainer) { # Calculate folder size $folderSize = (Get-ChildItem -Path $item.FullName -Recurse -File -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum / 1MB $Report += [PSCustomObject]@{ Path = $item.FullName Type = "Folder" SizeMB = "{0:N2}" -f $folderSize LastWrite = $item.LastWriteTime } } else { # Process files if ($MinAgeDays -gt 0 -and $item.LastWriteTime -lt (Get-Date).AddDays(-$MinAgeDays)) { # Skip if file is too new and age filter is active continue } if ($ExcludeExtension -contains $item.Extension) { # Skip if extension is excluded continue } $Report += [PSCustomObject]@{ Path = $item.FullName Type = "File" SizeMB = "{0:N2}" -f ($item.Length / 1MB) LastWrite = $item.LastWriteTime } } } } catch { Write-Warning "Could not access path '$p': $($_.Exception.Message)" } } } end { $Report | Sort-Object SizeMB -Descending } } COMMAND_BLOCK: # Get-DiskUsageReport -Path "C:\Temp", "\\Server\Share" -MinFileSizeKB 51200 -MinAgeDays 30 -Verbose | Format-Table -AutoSize # Get-DiskUsageReport -Path "C:\Users\Admin\Documents" -MinFileSizeKB 10240 -ExcludeExtension @(".tmp", ".bak") | Export-Csv -Path "C:\Reports\DiskUsage.csv" -NoTypeInformation Enter fullscreen mode Exit fullscreen mode COMMAND_BLOCK: # Get-DiskUsageReport -Path "C:\Temp", "\\Server\Share" -MinFileSizeKB 51200 -MinAgeDays 30 -Verbose | Format-Table -AutoSize # Get-DiskUsageReport -Path "C:\Users\Admin\Documents" -MinFileSizeKB 10240 -ExcludeExtension @(".tmp", ".bak") | Export-Csv -Path "C:\Reports\DiskUsage.csv" -NoTypeInformation COMMAND_BLOCK: # Get-DiskUsageReport -Path "C:\Temp", "\\Server\Share" -MinFileSizeKB 51200 -MinAgeDays 30 -Verbose | Format-Table -AutoSize # Get-DiskUsageReport -Path "C:\Users\Admin\Documents" -MinFileSizeKB 10240 -ExcludeExtension @(".tmp", ".bak") | Export-Csv -Path "C:\Reports\DiskUsage.csv" -NoTypeInformation - Setting up a dedicated lab environment (e.g., Hyper-V, VMware, Azure/AWS free tiers) is crucial for structured practice scenarios, allowing simulation of real-world IT administration tasks like user and service management. - Gamified platforms like PowerShell Koans offer self-guided, test-driven learning for core language constructs and syntax, while Hack The Box/TryHackMe provide objective-based challenges for applying PowerShell in complex IT/security contexts. - Project-based learning, such as building a ‘Disk Usage Reporter’ script, integrates multiple PowerShell concepts (e.g., Get-ChildItem, Measure-Object, Export-Csv, advanced functions, error handling) to create robust, reusable tools. - Mastering the PowerShell pipeline, understanding object flow, implementing robust error handling with try/catch, embracing parameterization, and frequently using Get-Help are essential best practices for exam preparation and efficient scripting. - Theoretical vs. Practical Gap: Knowing what a cmdlet does versus knowing when and how to apply it effectively in a real-world scenario. - Lack of Engaging Practice: Slogging through dry exercises can lead to burnout and poor retention. - Difficulty Simulating Real Environments: It’s hard to replicate complex IT infrastructures for practice without dedicated resources. - Uncertainty on Exam Question Styles: Not knowing if your practical skills align with the types of challenges you’ll face on the test. - Fear of Failure: The pressure of the exam can be overwhelming without a solid foundation of hands-on experience. - Set Up a Lab Environment: A dedicated virtual machine (VM) with Windows Server and/or client OS, ideally including Active Directory, is crucial. Hyper-V, VMware Workstation Player, or even Azure/AWS free tiers can serve this purpose. - Create Task Lists: Generate a list of realistic scenarios. Don’t just copy-paste; try to solve them from memory first, then refer to documentation. - Document Your Solutions: Write down the cmdlets, scripts, and reasoning behind your choices. This helps reinforce learning. - Review and Refine: After solving a problem, look for more efficient or robust ways to achieve the same result. - User Account Management (Active Directory or Local): Create a new user, set initial password, add to a security group. # For Active Directory (requires RSAT-AD-PowerShell) New-ADUser -Name "John Doe" -SamAccountName "jdoe" -UserPrincipalName "[email protected]" -Department "IT" -DisplayName "John Doe" -Enabled $true -AccountPassword (Read-Host -AsSecureString "Set password for jdoe") Add-ADGroupMember -Identity "IT Admins" -Members "jdoe" # For Local User $Password = ConvertTo-SecureString "P@ssword123!" -AsPlainText -Force New-LocalUser -Name "testuser" -Password $Password -PasswordNeverExpires $true -UserCannotChangePassword $true Add-LocalGroupMember -Group "Administrators" -Member "testuser" Find all users whose accounts are disabled or haven’t logged in for 90 days. # For Active Directory $CutoffDate = (Get-Date).AddDays(-90) Get-ADUser -Filter {Enabled -eq $false -or LastLogonDate -lt $CutoffDate} -Properties LastLogonDate | Select-Object Name, SamAccountName, LastLogonDate, Enabled - Create a new user, set initial password, add to a security group. - Find all users whose accounts are disabled or haven’t logged in for 90 days. - Service Management: Stop a specific service and configure it to start automatically on boot. Stop-Service -Name "BITS" -PassThru -Force Set-Service -Name "BITS" -StartupType Automatic List all services running under a specific account (e.g., ‘LocalSystem’). Get-Service | Where-Object {$_.StartName -eq "LocalSystem"} | Select-Object DisplayName, Name, StartName - Stop a specific service and configure it to start automatically on boot. - List all services running under a specific account (e.g., ‘LocalSystem’). - File System Operations: Find all files larger than 1GB in a specific directory and its subdirectories. Get-ChildItem -Path "C:\Data" -Recurse -File | Where-Object {$_.Length -gt 1GB} | Select-Object FullName, Length Change permissions for a folder to grant ‘Read’ access to a specific security group. $Path = "C:\SensitiveData" $ACL = Get-Acl $Path $AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("IT_Users", "Read", "ContainerInherit,ObjectInherit", "None", "Allow") $ACL.AddAccessRule($AccessRule) Set-Acl $Path $ACL - Find all files larger than 1GB in a specific directory and its subdirectories. - Change permissions for a folder to grant ‘Read’ access to a specific security group. - Create a new user, set initial password, add to a security group. - Find all users whose accounts are disabled or haven’t logged in for 90 days. - Stop a specific service and configure it to start automatically on boot. - List all services running under a specific account (e.g., ‘LocalSystem’). - Find all files larger than 1GB in a specific directory and its subdirectories. - Change permissions for a folder to grant ‘Read’ access to a specific security group. - PowerShell Koans: - Hack The Box / TryHackMe (PowerShell-focused modules): - TryHackMe Example: Look for rooms related to “Active Directory Basics,” “Windows PrivEsc (Privilege Escalation),” or “Windows Forensics.” Many tasks within these rooms will require using PowerShell to gather information, modify system settings, or automate tasks. - Practical Application: You might use Get-NetIPConfiguration to enumerate network settings, Get-Process to identify running applications, or Get-WmiObject to query system information – all critical skills for any PowerShell exam. - Identify a Problem: Think of a tedious, repetitive task you or your team faces. - Define Requirements: What should the script do? What inputs does it need? What output should it produce? - Break Down the Project: Divide the main goal into smaller, manageable functions or steps. - Implement Iteratively: Write small pieces of code, test them, and then integrate. - Focus on Best Practices: Use proper naming conventions, comment your code, implement error handling, and make it robust. - Get-ChildItem (with -Recurse) for file system enumeration. - Measure-Object for calculating total sizes. - Where-Object for filtering based on size, date, or extension. - Select-Object for custom output. - Export-Csv or ConvertTo-Html for report generation. - Functions and advanced parameters ([CmdletBinding()], [Parameter()]) for reusability and flexibility. - Error handling (try/catch) for inaccessible paths. - Active Learning is Key: Don't just read about cmdlets; execute them. Experiment with their parameters. - Master the Pipeline: Understand how objects flow from one cmdlet to another. This is fundamental to PowerShell efficiency. Use Get-Member to inspect object properties and methods. - Learn Error Handling: Implement try/catch/finally blocks and understand $ErrorActionPreference to make your scripts robust. - Embrace Parameterization: Write scripts that accept input parameters, making them reusable and flexible. - Read the Documentation: Use Get-Help -Full, Get-Help -Online, and Get-Help -Examples frequently. Understanding how to find information quickly is an exam skill in itself. - Practice Regularly: Consistency beats cramming. Dedicate short, regular sessions to practice. - Understand the "Why": Don't just memorize commands. Understand why certain cmdlets or approaches are used in specific scenarios.