Rob van der Woude's Scripting Pages
Powered by GeSHi

PowerShell Code Snippets

Filter and highlight code snippets by category:
Filter:
Highlight:
 

 

 

Console

1. Get PowerShell version

  1. Write-Host 'PowerShell Version' $PsVersionTable.PSVersion

 

2. Get the script's own (full) command line

  1. [System.Environment]::CommandLine # single string including powershell executable and script name
  2. [System.Environment]::GetCommandLineArgs( ) # array of strings including powershell executable and script name
  3. $Args # array of strings, script arguments only

 

3. Suppress Standard Output

  1. some-command | Out-Null # slow
  2. some-command > $null # fast and easier to understand for shell afficionados
  3. [void] some-command # fastest, but works only if output is object, not if written to screen with Write-Host
  4. $dummy = some-command( ) # alternative; your IDE may complain about unused variable $dummy

 

4. Suppress Standard Error

  1. some-command -ErrorAction SilentlyContinue
  2. some-command 2> $null # for shell afficionados

 

5. Suppress all output

  1. some-command -ErrorAction SilentlyContinue | Out-Null # slow
  2. some-command > $null 2>&1 # fast and easier to understand for shell afficionados
  3. [void] some-command -ErrorAction SilentlyContinue # fast, but won't work if output is written to screen with Write-Host
  4.  

 

6. Set exit code ("Errorlevel")

  1. $Host.SetShouldExit( -1 ) # for exit code -1

 

7. Get OS version

  1. # Windows version (as in VER command)
  2. [Environment]::OSVersion
  3.  
  4. # or, using WMI:
  5. Get-CimInstance -Class Win32_OperatingSystem
  6.  
  7. # Windows edition (requires elevated privileges):
  8. Get-WindowsEdition –Online
  9.  
  10. # friendly name (as in WinVer command):
  11. $winver = ( Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" )
  12. "{0} {1}" -f $winver.ProductName, $winver.DisplayVersion

 

8. List all "static" environment variables

  1. [environment]::GetEnvironmentVariables( )

 

9. Get current directory (and more)

  1. "Current directory        :  {0}" -f $( Get-Location ).Path
  2. "Current drive root       :  {0}" -f $( Get-Location ).Drive.Root
  3. "Current drive free space :  {0:F0} GB" -f $( ( Get-Location ).Drive.Free / 1GB )

 

10. List all special folders

  1. # Inspired by "#PSTip Working with Special Folders" by Shay Levy
  2. # https://powershellmagazine.com/2013/10/30/pstip-working-with-special-folders/
  3. # option 1: display results in GridView
  4. $specialfolders = [ordered]@{ } # create a Dictionary object
  5. [Enum]::GetNames( 'System.Environment+SpecialFolder' ) | Sort-Object | ForEach-Object {
  6. 	$specialfolders.Add( $_, [Environment]::GetFolderPath( $_ ) ) # add each key/value pair to the Dictionary
  7. }
  8. $specialfolders | Out-GridView -Title 'Special Folders' -PassThru # show results in GridView
  9.  
  10. # option 2: display results in the console itself:
  11.  
  12. $columnwidth = 'Special Folder Name'.Length
  13. [Enum]::GetNames( 'System.Environment+SpecialFolder' ) | ForEach-Object {
  14. 	$columnwidth = [Math]::Max( $columnwidth, $_.Length )
  15. }
  16. ( "{0,-$columnwidth}    {1}" -f 'Special Folder Name', 'Location' )
  17. ( "{0,-$columnwidth}    {1}" -f '===================', '========' )
  18. # [Enum]::GetNames( 'System.Environment+SpecialFolder' ) or [Enum]::GetNames( [System.Environment+SpecialFolder] )
  19. [Enum]::GetNames( 'System.Environment+SpecialFolder' ) | ForEach-Object {
  20. 	( "{0,-$columnwidth}    {1}" -f $_, [Environment]::GetFolderPath( $_ ) )
  21. } | Sort-Object

 

And this is what the result of Out-GridView will look like:

Screenshot of Special Folders list in GridView

11. List all Shell Folders

  1. # Source: "Shell folders: the best-kept Windows time saving secret" by Mike Williams
  2. # https://www.techradar.com/news/computing/pc/shell-folders-the-best-kept-windows-time-saving-secret-464668
  3. $registrypath = 'HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\FolderDescriptions'
  4. $shellfolders = $( Get-ChildItem -Path $registrypath | Get-ItemProperty | Select-Object -Property Name,ParsingName -ErrorAction Ignore | Sort-Object { $_.Name } )
  5. $shellfolders | Format-List
  6.  
  7. # or in GridView:
  8.  
  9. $shellfolders | Out-GridView -Title 'Shell Folders' -PassThru
  10.  
  11. # or a fancy presentation in the console itself, the hard way:
  12.  
  13. [Console]::BackgroundColor = [ConsoleColor]::White
  14. [Console]::ForegroundColor = [ConsoleColor]::Black
  15. Clear-Host
  16. # gather the information
  17. $registrypath = 'HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\FolderDescriptions'
  18. $shellfolders = $( Get-ChildItem -Path $registrypath | Get-ItemProperty | Select-Object -Property Name,ParsingName -ErrorAction Ignore | Sort-Object { $_.Name } )
  19. # calculate required column widths
  20. $consolewidth = [Console]::WindowWidth
  21. $colwidthName = $( $shellfolders.Name | Measure-Object -Property Length -Maximum ).Maximum
  22. $remaining    = $consolewidth - $colwidthName -4
  23. # write a header
  24. "{0,-$colwidthName}   {1,-$remaining}" -f 'Name', 'ParsingName'
  25. [Console]::BackgroundColor = [ConsoleColor]::Gray
  26. # underline the header
  27. "{0,-$colwidthName}   {1,-$remaining}" -f ( '=' * 'Name'.Length ), ( '=' * 'ParsingName'.Length )
  28. [Console]::BackgroundColor = [ConsoleColor]::White
  29. # present the gathered information
  30. $shellfolders | ForEach-Object {
  31. 	"{0,-$colwidthName}   {1,-$remaining}" -f $_.Name, $_.ParsingName
  32. 	# alternate background color for easier reading
  33. 	if ( [Console]::BackgroundColor -eq [ConsoleColor]::White ) {
  34. 		[Console]::BackgroundColor = [ConsoleColor]::Gray
  35. 	} else {
  36. 		[Console]::BackgroundColor = [ConsoleColor]::White
  37. 	}
  38. }
  39. [Console]::BackgroundColor = [ConsoleColor]::White
  40. ""
  41. [Console]::ResetColor( )

 

And this is what the result of Out-GridView will look like:

Screenshot of Shell Folders list in GridView

And this is what the result of the "fancy" code will look like in the console:

Screenshot of fance Shell Folders code

12. Get directory size and number of files

  1. $directory = $( [Environment]::GetFolderPath( 'MyDocuments' ) ) # or specify any other directory
  2. $dirsize   = $( Get-ChildItem -Path $directory -Recurse | Measure-Object -Property Length -Sum )
  3. "Directory `"{0}`" contains {1} files with a total size of {2:F2} GB" -f $directory, $dirsize.Count, ( $dirsize.Sum / 1GB )

 

13. Check if files are identical

  1. # Specify $file1 and $file2
  2. $identical = ( ( Get-FileHash -Algorithm MD5 -Path $file1 ).Hash -eq ( Get-FileHash -Algorithm MD5 -Path $file2 ).Hash )

 

14. Empty the Recycle Bin (silently)

  1. $def = @"
  2. public enum RecycleFlags : UInt32
  3. {
  4. 	RecycleNoConfirmation = 0x00000001,
  5. 	RecycleNoProgressUI = 0x00000002,
  6. 	RecycleNoSound = 0x00000004
  7. }
  8.  
  9. [DllImport( "Shell32.dll", CharSet = CharSet.Unicode )]
  10. public static extern UInt32 SHEmptyRecycleBin( IntPtr hwnd, string pszRootPath, RecycleFlags dwFlags );
  11. "@
  12.  
  13. if ( -not ( [System.Management.Automation.PSTypeName]'NativeMethods.Shell32Dll' ).Type ) {
  14. 	Add-Type -Namespace NativeMethods -Name Shell32Dll -MemberDefinition $def -ReferencedAssemblies System.Runtime.InteropServices
  15. }
  16. $flags  = [NativeMethods.Shell32Dll+RecycleFlags]::RecycleNoConfirmation
  17. $flags += [NativeMethods.Shell32Dll+RecycleFlags]::RecycleNoProgressUI
  18. $flags += [NativeMethods.Shell32Dll+RecycleFlags]::RecycleNoSound
  19. [void][NativeMethods.Shell32Dll]::SHEmptyRecycleBin( [IntPtr]::Zero, 'D:', $flags ) # repeat this command for each drive

 

15. Get console width in characters

  1. $Host.UI.RawUI.WindowSize.Width
  2.  
  3. # or:
  4.  
  5. [console]::WindowWidth

 

16. Get screen width in pixels

  1. Add-Type -AssemblyName System.Windows.Forms
  2. ( [System.Windows.Forms.Screen]::AllScreens | where-Object { $_.Primary } ).WorkingArea.Width # current value for primary monitor
  3.  
  4. # or:
  5.  
  6. [System.Windows.Forms.SystemInformation]::PrimaryMonitorSize.Width # current value for primary monitor
  7.  
  8. # or:
  9.  
  10. [System.Windows.Forms.SystemInformation]::PrimaryMonitorMaximizedWindowSize.Width # maximum available width on primary monitor
  11.  
  12. # or:
  13.  
  14. ( Get-CimInstance -ClassName Win32_DesktopMonitor ).ScreenWidth # maximum value for primary monitor
  15.  
  16. # or:
  17.  
  18. ( Get-CimInstance -ClassName Win32_VideoController ).CurrentHorizontalResolution # current value for single video card and monitor

 

17. Count monitors currently connected

  1. $wmiclass     = "Win32_DesktopMonitor"
  2. $wminamespace = "root/CIMV2"
  3. $wmiquery     = "MonitorManufacturer IS NOT NULL AND NOT MonitorType='Default Monitor'" # exclude disconnected monitors
  4. $monitors     = Get-CimInstance -ClassName $wmiclass -Namespace $wminamespace -Filter $wmiquery
  5. $count        = ( $monitors | Measure-Object ).Count
  6. if ( $count -eq 0 ) {
  7. 	Write-Host "`nNo" -ForegroundColor Red -NoNewline
  8. 	Write-Host " monitor detected"
  9. } elseif ( $count -eq 1 ) {
  10. 	Write-Host "`n1" -ForegroundColor Green -NoNewline
  11. 	Write-Host " monitor detected:"
  12. } else {
  13. 	Write-Host "`n$count" -ForegroundColor Green -NoNewline
  14. 	Write-Host " monitors detected:"
  15. }
  16. # List monitor manufacturers and types
  17. foreach ( $monitor in $monitors ) {
  18. 	Write-Host "`t" -NoNewline
  19. 	Write-Host ( "{0} {1}" -f $monitor.MonitorManufacturer, $monitor.MonitorType ).Trim( )
  20. }

 

18. Check if all monitors have equal resolutions

  1. Add-Type -AssemblyName System.Windows.Forms
  2. $monitorcount  = [System.Windows.Forms.SystemInformation]::MonitorCount
  3. $monitorsequal = [System.Windows.Forms.SystemInformation]::MonitorsSameDisplayFormat
  4. if ( $monitorcount -eq 1 ) {
  5. 	Write-Host "single monitor"
  6. } else {
  7. 	Write-Host ( "{0} monitors " -f $monitorcount ) -NoNewline
  8. 	if ( $monitorsequal ) {
  9. 		Write-Host "of equal resolution"
  10. 	} else {
  11. 		Write-Host "with different resolutions"
  12. 	}
  13. }

 

19. Console colors demo

  1. [console]::ForegroundColor = 'Yellow'
  2. [console]::BackgroundColor = 'Blue'
  3. Clear-Host
  4. $linelength = [console]::WindowWidth
  5. "`n Line length (console width) = $linelength characters`n"
  6. Write-Host ( "{0,-$linelength}" -f ' A full length black and white line' ) -ForegroundColor Black -BackgroundColor White
  7. Write-Host "`n A single " -NoNewline
  8. Write-Host "m" -NoNewline -BackgroundColor Black -ForegroundColor Magenta
  9. Write-Host "u" -NoNewline -BackgroundColor Black -ForegroundColor Red
  10. Write-Host "l" -NoNewline -BackgroundColor Black -ForegroundColor DarkYellow
  11. Write-Host "t" -NoNewline -BackgroundColor Black -ForegroundColor Yellow
  12. Write-Host "i" -NoNewline -BackgroundColor Black -ForegroundColor Green
  13. Write-Host "-" -NoNewline -BackgroundColor Black -ForegroundColor Blue
  14. Write-Host "c" -NoNewline -BackgroundColor Black -ForegroundColor White
  15. Write-Host "o" -NoNewline -BackgroundColor Black -ForegroundColor Magenta
  16. Write-Host "l" -NoNewline -BackgroundColor Black -ForegroundColor Red
  17. Write-Host "o" -NoNewline -BackgroundColor Black -ForegroundColor DarkYellow
  18. Write-Host "r" -NoNewline -BackgroundColor Black -ForegroundColor Yellow
  19. Write-Host "e" -NoNewline -BackgroundColor Black -ForegroundColor Green
  20. Write-Host "d" -NoNewline -BackgroundColor Black -ForegroundColor Blue
  21. Write-Host " word`n`n"
  22.  
  23. Write-Host ' List and show all console colors'
  24. Write-Host ' --------------------------------'
  25. [Enum]::GetNames( 'System.ConsoleColor' ) | ForEach-Object {
  26. 	Write-Host ( " [{0,2}]`t{1,-26}" -f [int][ConsoleColor]$_, $_ ) -ForegroundColor $_ -BackgroundColor ( ( [int][ConsoleColor]$_ + 2 ) % 16 )
  27. }

 

And this is what the result of the previous code will look like:

Screenshot of PowerShell Console Colors Demo

20. Format numbers

  1. # More detailed information can be found at
  2. # https://ss64.com/ps/syntax-f-operator.html
  3. Write-Host 'Dec   Hex'
  4. Write-Host '===   ==='
  5. 0..128 | ForEach-Object {
  6. 	# {argument[,padding][:type and digits]}
  7. 	# {0} is first argument;
  8. 	# {0,4} align/pad first argument to at least 4 positions
  9. 	# {0,3:D2} align first argument at least 3 positions, use at least 2 decimal digits
  10. 	# {0,2:X2} align first argument at least 2 positions, use at least 2 upper case hexadecimal digits
  11. 	Write-Host ( '{0,3:D2} = 0x{0,2:X2}' -f ( $_ * 8 ) )
  12. }

 

And this is what the result of the previous code will look like:

Screenshot of PowerShell Format Numbers demo

21. Format numbers, take 2

  1. " Decimal`tBinary`tOctal`tHexadecimal"
  2. " =======`t======`t=====`t==========="
  3. 0..31 | ForEach-Object { "  {0,6}`t{1,6}`t{2,5}`t     0x{0:X4}" -f $_, [Convert]::ToString( $_, 2 ), [Convert]::ToString( $_, 8 ) }

 

And this is what the result of the previous code will look like:

Screenshot of PowerShell Format Numbers demo

22. Get the weeknumber (week of year)

  1. $now = $( Get-Date )  # or [DateTime]::Now
  2. $calendarWeekRule = 2 # first 4-day week, see https://docs.microsoft.com/en-us/dotnet/api/system.globalization.calendarweekrule
  3. $firstDayOfWeek   = 1 # Monday, see https://docs.microsoft.com/en-us/dotnet/api/system.dayofweek
  4. [System.Globalization.DateTimeFormatInfo]::CurrentInfo.Calendar.GetWeekOfYear( $now, $calendarWeekRule, $firstDayOfWeek )

 

23. Get the number of days till the first day of next month

  1. $nextmonth = ( Get-Date -Day 1 ).AddMonths( 1 ).Date
  2. $today = ( Get-Date ).Date
  3. "{0} days left this month (including today)" -f ( $nextmonth - $today ).Days

 

24. Check if current year is a leap year

  1. $year = ( Get-Date ).Year
  2. $leapyear = [DateTime]::IsLeapYear( $year )
  3.  
  4. # or by checking the number of days in a year, tip from Joe Caverly:
  5.  
  6. $leapyear = ( ( [DateTime] "$year-12-31" ).DayOfYear -eq 366 )
  7.  
  8. # ditto, but without requiring variable $year:
  9.  
  10. $leapyear = ( ( Get-Date -Month 12 -Day 31 ).DayOfYear -eq 366 )
  11.  
  12. # or by checking if February has 29 days:
  13.  
  14. $leapyear = ( [DateTime]::DaysInMonth( $year, 2 ) -eq 29 )
  15.  
  16. # ditto, but without requiring variable $year:
  17.  
  18. $leapyear = ( ( Get-Date -Month 3 -Day 1 ).AddDays( -1 ).Day -eq 29 )
  19.  
  20. # or, the hard way:
  21.  
  22. [bool]$leapyear = ( [bool]!( $year % 4 ) -and [bool]( $year % 100 ) ) -or [bool]!( $year % 400 )

 

25. Translate weekday and month names

  1. [System.Globalization.CultureInfo]::CurrentCulture.DateTimeFormat.DayNames              # weekday names in current language
  2. [System.Globalization.CultureInfo]::CurrentCulture.DateTimeFormat.MonthNames            # month   names in current language
  3. [System.Globalization.CultureInfo]::GetCultureInfo( 'nl' ).DateTimeFormat.DayNames      # weekday names in Dutch  (NL)
  4. [System.Globalization.CultureInfo]::GetCultureInfo( 'nl' ).DateTimeFormat.MonthNames    # months  names in Dutch  (NL)
  5. [System.Globalization.CultureInfo]::GetCultureInfo( 'de' ).DateTimeFormat.DayNames      # weekday names in German (DE)
  6. [System.Globalization.CultureInfo]::GetCultureInfo( 'de' ).DateTimeFormat.MonthNames    # months  names in German (DE)
  7. [System.Globalization.CultureInfo]::GetCultureInfo( 'fr' ).DateTimeFormat.DayNames      # weekday names in French (FR)
  8. [System.Globalization.CultureInfo]::GetCultureInfo( 'fr' ).DateTimeFormat.MonthNames    # months  names in French (FR)
  9. [System.Globalization.CultureInfo]::GetCultureInfo( 'pt' ).DateTimeFormat.DayNames[0]   # 'domingo' = Sunday in Portuguese (PT)
  10. [System.Globalization.CultureInfo]::GetCultureInfo( 'es' ).DateTimeFormat.MonthNames[2] # 'marzo'   = March  in Spanish    (ES)
  11. # List all cultures/languages:
  12. [System.Globalization.CultureInfo]::GetCultures( [System.Globalization.CultureTypes]::AllCultures )

 

26. Countdown to next Christmas

  1. $today = ( Get-Date )
  2. $year = $today.Year
  3. if ( ( $today.Month -eq 12 ) -and ( $today.Day -ge 25 ) ) {
  4. 	$year += 1 # add 1 year if we are past Christmas this year
  5. }
  6. $christmas = ( Get-Date "$year-12-25" )
  7. $wait = ( New-TimeSpan -Start $today -End $christmas )
  8. Write-Host ( "Please be patient for another {0} day(s)" -f $wait.Days )

 

27. Calculate Easter date for any year

  1. # Easter is at first Sunday after the first full moon at or after the Spring equinox (21 March)
  2. # Calculation explained: https://www.timeanddate.com/calendar/determining-easter-date.html
  3. Set-Variable -Name ReferenceFullMoon -Option Constant -Value $( Get-Date -Date '2022-01-17 23:48' ) -ErrorAction Ignore
  4. Set-Variable -Name MoonCycleDays     -Option Constant -Value 29.53                                  -ErrorAction Ignore
  5. if ( $args.Length -eq 1 ) {
  6. 	$year = $args[0] # enclose year in quotes if less than 100, and always use 4 digits, e.g. '0033'
  7. } else {
  8. 	$year = $( Get-Date ).Year # or specify any other year on the command line
  9. }
  10. # For Easter calculations, the Spring equinox is always assumed to be at 21 March
  11. $springequinox = $( Get-Date -Date "$year-03-21" ) # 21 March
  12. # Calculate full moon cycles to first full moon after Spring equinox of specified year
  13. $fullcycles = [Math]::Ceiling( ( New-TimeSpan -Start $ReferenceFullMoon -End $springequinox ).Days / $MoonCycleDays )
  14. # Date of first full moon after Spring equinox of specified year
  15. $fullmoonafterequinox = $ReferenceFullMoon.AddDays( $fullcycles * $MoonCycleDays )
  16. # First Sunday following first full moon at or after Spring equinox of specified year
  17. $eastersunday = $fullmoonafterequinox.AddDays( 7 - [int]$fullmoonafterequinox.DayOfWeek ).Date
  18. # Display the result
  19. if ( ( New-TimeSpan -Start ( Get-Date ).Date -End $eastersunday ).Days -lt 0 ) {
  20. 	"Easter {0} was at {1}" -f $year, $eastersunday.ToLongDateString( )
  21. } else {
  22. 	"Easter {0} will be at {1}" -f $year, $eastersunday.ToLongDateString( )
  23. }

 

28. Julian date math

  1. # Code to convert today's (Gregorian) date to Julian date by David Yaw: https://stackoverflow.com/a/5254812
  2. $juliandate = ( Get-Date ).Date.ToOADate( ) + 2415018.5
  3. # or (see https://en.wikipedia.org/wiki/Julian_day#Variants for details):
  4. $juliandate = ( Get-Date ).Date.Ticks / 864000000000 + 1721425.5
  5.  
  6. # Convert Julian date back to Gregorian date:
  7. $gregoriandate = [DateTime]::FromOADate( $juliandate - 2415018.5 )
  8. # or:
  9. $gregoriandate = $( Get-Date -Date '0001-01-01' ).AddTicks( ( $juliandate - 1721425.5 ) * 864000000000 )
  10.  
  11. # Demo: convert between Gregorian and Julian dates:
  12. $todaygregorian = $( Get-Date ).Date
  13. "Gregorian date for today    : {0}" -f $todaygregorian.ToString( 'yyyy-MM-dd' )
  14. $juliandate = $todaygregorian.ToOADate( ) + 2415018.5 # or: $todaygregorian.Ticks / 864000000000 + 1721425.5
  15. "Converted to Julian date    : $juliandate"
  16. $gregoriandate = [DateTime]::FromOADate( $juliandate - 2415018.5 ) # or: $( Get-Date -Date 0001-01-01 ).AddTicks( ( $juliandate - 1721425.5 ) * 864000000000 )
  17. "Converted back to Gregorian : {0}" -f $gregoriandate.ToString( 'yyyy-MM-dd' )

 

And this is what the result of the previous demo code will look like in a PowerShell console:

Gregorian date for today    : 2024-03-19
Converted to Julian date    : 2460388.5
Converted back to Gregorian : 2024-03-19

29. HTML escape text

  1. Add-Type -AssemblyName System.Net
  2. $unescapedtext = '4 > 3'
  3. $escapedtext = [System.Net.WebUtility]::HtmlEncode( $unescapedtext );
  4. $escapedtext

 

30. Create a unique temporary file

  1. $tempfile = New-TemporaryFile

 

31. Remove duplicate lines

  1. some-command | Get-Unique

 

32. Retrieve a single line from a text file

  1. # Retrieve line 25 of file 'some_text_file.txt'
  2. ( Get-Content 'some_text_file.txt' -TotalCount 25 )[-1]
  3. # Alternative way to retrieve line 25 of file 'some_text_file.txt'
  4. ( Get-Content 'some_text_file.txt' )[24]

 

33. Retrieve several lines from a text file

  1. # Retrieve first 15 lines of file 'some_text_file.txt'
  2. Get-Content 'some_text_file.txt' -TotalCount 15
  3. # Get lines 20..25 of file 'some_text_file.txt'
  4. ( Get-Content 'some_text_file.txt' -TotalCount 25 )[-5..-1]
  5. # Retrieve last 5 lines of file 'some_text_file.txt'
  6. Get-Content 'some_text_file.txt' -Tail 5
  7. # Alternative way to retrieve last 5 lines of file 'some_text_file.txt'
  8. ( Get-Content 'some_text_file.txt' )[-5..-1]

 

34. Archive files into a ZIP file

  1. # . . . . . . . . . files to archive  . . . . . . . . . ZIP file . . . . . best compression . . add to existing ZIP file
  2. Compress-Archive -Path 'd:\folder' -DestinationPath 'd:\zipfile.zip' -CompressionLevel Optimal -Update

 

35. Extract files from a ZIP file

  1. # Extract ZIP file into a subfolder with the ZIP file's name; use -DestiantionPath to specify an alternative destination
  2. Expand-Archive -Path 'd:\zipfile.zip' -Force

 

36. Send text to clipboard

  1. Set-Clipboard -Value 'new clipboard text'          # overwrite
  2.  
  3. # or:
  4.  
  5. Set-Clipboard -Value 'more clipboard text' -Append # append

 

37. Paste text from clipboard

  1. Get-Clipboard
  2.  
  3. # or the hard way:
  4.  
  5. Add-Type -AssemblyName System.Windows.Forms
  6. [System.Windows.Forms.Clipboard]::GetText( [System.Windows.Forms.TextDataFormat]::UnicodeText )

 

38. Send files to clipboard

  1. Add-Type -AssemblyName System.Windows.Forms
  2. $filelist = @( Get-ChildItem -Path 'd:\folder\filenames*.*' ) # array of file names
  3. [System.Windows.Forms.Clipboard]::SetFileDropList( $filelist )

 

39. Paste files from clipboard

  1. # This script uses SendKeys to paste files from the clipboard into an Explorer window.
  2. # This is ABSOLUTELY NOT a recommended procedure, as it is extremely error-prone.
  3. $def = @"
  4. [DllImport( "user32.dll" )]
  5. [return: MarshalAs( UnmanagedType.Bool )]
  6. public static extern bool SetForegroundWindow( IntPtr hWnd );
  7. "@ # C# code to set foreground window
  8. Add-Type -Namespace NativeMethods -Name User32Dll -MemberDefinition $def -ReferencedAssemblies System.Runtime.InteropServices
  9. Add-Type -AssemblyName System.Windows.Forms
  10. Start-Process -FilePath 'explorer.exe' -ArgumentList "$Env:Temp" # open TEMP directory in Explorer
  11. Start-Sleep -Milliseconds 500 # wait half a second
  12. [IntPtr]$handle = $( Get-Process -Name 'explorer' | Where-Object { $_.MainWindowTitle -eq "$Env:Temp" } )[0].MainWindowHandle
  13. [NativeMethods.User32Dll]::SetForegroundWindow( $handle ) # make Explorer the foreground window
  14. Start-Sleep -Milliseconds 500 # wait half a second
  15. [System.Windows.Forms.SendKeys]::SendWait( "+{INSERT}" ) # send Shift-Ins keystroke to paste files into TEMP directory

 

40. Ask for input

  1. # Multiple characters, case sensitive string, terminated with Enter
  2. # =================================================================
  3. $input = Read-Host -Prompt "Enter your name"
  4.  
  5. # or:
  6.  
  7. Write-Host "Enter your name " -NoNewLine
  8. $input = $Host.UI.ReadLine( )
  9.  
  10. # Single charater (note that ReadKey accepts ALL keys including function keys F2..F12, Enter and Esc)
  11. # ===================================================================================================
  12. # Case sensitive, hide input $true
  13. $key = [System.Console]::ReadKey( $true ).KeyChar
  14.  
  15. # Upper case character or special key's caption (e.g. 'Enter'), hide input $true
  16. $key = [System.Console]::ReadKey( $true ).Key
  17.  
  18. # Limited range of characters accepted (case sensitive if letters)
  19. $input = ''
  20. $range = '[1-5]' # regular expression
  21. do {
  22. 	Write-Host 'Choose a number from 1 to 5: ' -NoNewline
  23. 	$input = [System.Console]::ReadKey( $false ).KeyChar
  24. 	# Clear the line to either prompt again or show the accepted result
  25. 	Write-Host ( "`b `b" * $Host.UI.RawUI.CursorPosition.X ) -NoNewline
  26. } until ( $input -match $range )
  27.  
  28. Write-Host "You chose $input"
  29.  
  30. # Limited range of strings, type the string of choice (not case sensitive) or press Enter for the default
  31. # =======================================================================================================
  32. $title = 'Printer Selection'
  33. $message = 'Pick one of the following printers:'
  34. $options = ( Get-Printer ).Name
  35. $defaultprinter = ( Get-CimInstance -ClassName Win32_Printer -Filter "Default=TRUE" ).Name
  36. $defaultchoice = $options.IndexOf( $defaultprinter )
  37. $selected = $host.UI.PromptForChoice( $title , $message, $options, $defaultchoice )
  38. $options[$selected]

 

And this is what the result of the previous PromptForChoice code will look like in a PowerShell console:

Printer Selection
Pick one of the following printers:
[] OneNote (Desktop) [] Microsoft XPS Document Writer [] Microsoft Print to PDF [] Fax [] HP LaserJet P2055DN [?] Help (default is "HP LaserJet P2055DN"):

And this is what the result of the previous PromptForChoice code will look like in PowerShell ISE:

Screenshot of PowerShell PromptForChoice demo in PowerShell ISE

Check out Dirk's A nicer PromptForChoice for the PowerShell Console Host article for a more consistent looking alternative to PromptForChoice.

41. Check elevation

  1. # More details on https://superuser.com/questions/749243/detect-if-powershell-is-running-as-administrator
  2. $currentPrincipal = New-Object Security.Principal.WindowsPrincipal( [Security.Principal.WindowsIdentity]::GetCurrent( ) )
  3. if ( -not ( $currentPrincipal.IsInRole( [Security.Principal.WindowsBuiltInRole]::Administrator ) ) )
  4. {
  5. 	Write-Error "This script must be executed in admin mode." -ErrorAction Stop
  6. }
  7.  
  8. # or:
  9.  
  10. if ( -not ( [Security.Principal.WindowsIdentity]::GetCurrent( ).Groups -contains 'S-1-5-32-544' ) ) # S-1-5-32-544 is the local Administrators group
  11. {
  12. 	Write-Error "This script must be executed in admin mode." -ErrorAction Stop
  13. }
  14.  
  15. # or:
  16.  
  17. #Requires -RunAsAdministrator
  18. # The "#Requires" statement above will make the script abort with error message if not run as administrator
  19. # See https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_requires for details

 

42. Abort if member of Administrators

  1. if ( [Security.Principal.WindowsIdentity]::GetCurrent( ).Groups -contains 'S-1-5-32-544' )
  2. {
  3. 	Write-Error "This script must NOT be executed by members of the Administrators group." -ErrorAction Stop
  4. }

 

43. Restart the script with elevated privileges

  1. $progpath = ( Get-Command ( [System.Environment]::GetCommandLineArgs( ) )[0] ).Definition
  2. if ( $PSVersionTable.PSVersion.Major -gt 5 ) {
  3. 	# PowerShell 7 console states pwsh.dll as its executable, we'll use pwsh.exe instead
  4. 	$progpath = $progpath -replace 'pwsh\.dll$', 'pwsh.exe'
  5. }
  6. if ( $args.Length -eq 0 ) {
  7. 	Start-Process -FilePath $progpath -Verb RunAs
  8. } else {
  9. 	Start-Process -ArgumentList $args -FilePath $progpath -Verb RunAs
  10. }

 

44. Underline text in console

  1. Write-Host $sometext
  2. Write-Host ( "-" * $sometext.Length ) # single underline
  3. Write-Host ( "=" * $sometext.Length ) # double underline

 

45. Find a file in the PATH

  1. ( Get-Command $file ).Definition # $file is the file to be found, e.g. "powershell.exe"

 

46. List drive letters in use

  1. [environment]::GetLogicalDrives( )
  2.  
  3. # or:
  4. ( Get-PSDrive -Name ? ).Name
  5.  
  6. # or:
  7. ( Get-Location ).Provider.Drives.Name
  8.  
  9. # or:
  10. ( Get-PSDrive -PSProvider FileSystem ).Name
  11.  
  12. # or the hard way:
  13. ( Get-PSDrive | Where-Object { $_.Name -match '^[A-Z]$' } ).Name
  14.  
  15. # or local drives only (excluding network drives):
  16. ( Get-Volume ).DriveLetter

 

47. Find unused drive letters

  1. $drivesinuse = ( Get-Location ).Provider.Drives.Name
  2. 65..90 | ForEach-Object {
  3. 	if ( $drivesinuse.Contains( "{0}" -f [char]$_ ) ) {
  4. 		Write-Host ( "{0}:`tUSED" -f [char]$_ ) -ForegroundColor Red
  5. 	} else {
  6. 		Write-Host ( "{0}:`tFREE" -f [char]$_ ) -ForegroundColor Green
  7. 	}
  8. }

 

48. Find the drive with the largest amount of free space

  1. $drive = ( Get-Volume | Where-Object { $_.DriveType -eq 'Fixed' } | Sort-Object { $_.SizeRemaining } | Select-Object -Last 1 )
  2. Write-Host ( "Drive with most free space     {0}:" -f $drive.DriveLetter )
  3. Write-Host ( "Total size of drive {0}:         {1:F0} GB" -f $drive.DriveLetter, ( $drive.Size / 1GB ) )
  4. Write-Host ( "Free space on drive {0}:         {1:F0} GB" -f $drive.DriveLetter, ( $drive.SizeRemaining / 1GB ) )
  5. Write-Host ( "Percentage of free space       {0:F0}%" -f ( 100 * $drive.SizeRemaining / $drive.Size ) )

 

49. Beep

  1. # Standard beep:
  2. [Console]::Beep( )
  3.  
  4. # Custom beep:
  5. [Console]::Beep( $frequency, $milliseconds ) # frequency 37..32767 Hz
  6.  
  7. # Melody demo:
  8. @( 392, 330, 349, 247, 32767, 330, 349, 392, 330 ) | ForEach-Object { [Console]::Beep( $_, 500 ) } # use 32767 for pauses

 

50. Wait

  1. Start-Sleep -Seconds 10 # wait 10 seconds
  2. Start-Sleep 10 # wait 10 seconds
  3. Start-Sleep -Seconds 2.7 # wait 3 seconds, rounded to integer
  4. Start-Sleep -MilliSeconds 500 # wait half a second

 

51. Quick-and-dirty ASCII table

  1. 0..255 | ForEach-Object { Write-Host ( "{0}`t{1}" -f $_,[char]$_ ) }

 

52. Fancy ASCII table

  1. $columns = 8 # Number of columns, use any power of 2 to make the table fit on screen
  2. 0..( $columns - 1 ) | ForEach-Object {
  3. 	if ( $_ -eq 0 ) {
  4. 		Write-Host "Decimal`tASCII" -NoNewline
  5. 	} else {
  6. 		Write-Host "`t`tDecimal`tASCII" -NoNewline
  7. 	}
  8. }
  9. Write-Host
  10. 0..( $columns - 1 ) | ForEach-Object {
  11. 	if ( $_ -eq 0 ) {
  12. 		Write-Host "=======`t=====" -NoNewline
  13. 	} else {
  14. 		Write-Host "`t`t=======`t=====" -NoNewline
  15. 	}
  16. }
  17. Write-Host
  18. 0..( ( 256 / $columns ) - 1 ) | ForEach-Object {
  19. 	$startvalue = $columns * $_
  20. 	0..( $columns - 1 ) | ForEach-Object {
  21. 		$charvalue = $startvalue + $_
  22. 		if ( $_ -eq 0 ) {
  23. 			Write-Host ( "{0,7}`t{1,5}" -f $charvalue,[char]$charvalue ) -NoNewline
  24. 		} else {
  25. 			Write-Host ( "`t`t{0,7}`t{1,5}" -f $charvalue,[char]$charvalue ) -NoNewline
  26. 		}
  27. 	}
  28. 	Write-Host
  29. }

 

And this is what the result of the previous code will look like, depending on your codepage:

Screenshot of PowerShell generated ASCII Table

53. Get the computer's workgroup or domain

  1. $computerinfo = ( Get-ComputerInfo )
  2. if ( $computerinfo.CsPartOfDomain ) {
  3. 	Write-Host( "Domain: {0}" -f $computerinfo.CsDomain )
  4. } else {
  5. 	Write-Host( "Workgroup: {0}" -f $computerinfo.CsWorkgroup )
  6. }

 

54. Find the host name of any computer by its IP address

  1. # Source: https://morgantechspace.com/2015/06/powershell-find-machine-name-from-ip-address.html
  2. # Replace 127.0.0.1 with any other IP address
  3. [System.Net.Dns]::GetHostByAddress('127.0.0.1').HostName

 

55. Show your local IP address (or the IP address of any other computer)

  1. # Source: https://morgantechspace.com/2015/06/powershell-find-machine-name-from-ip-address.html
  2. # Replace $Env:ComputerName with any other computer name
  3. [System.Net.Dns]::GetHostByName( $Env:ComputerName ).AddressList[0].IPAddressToString
  4.  
  5. # or:
  6.  
  7. [System.Net.Dns]::Resolve( $env:ComputerName ).AddressList[0].IPAddressToString

 

56. Show your remote IP address

  1. # wanip.php contains only this code: <?php print $_SERVER['REMOTE_ADDR']; ?>
  2. Write-Host 'My IP address is:' ( Invoke-WebRequest -Uri https://www.robvanderwoude.com/wanip.php ).Content

 

And this is what you will get:

My IP address is: 54.221.159.188

57. Check lock keys status

  1. Add-Type -AssemblyName System.Windows.Forms
  2. $capslock   = [System.Windows.Forms.Control]::IsKeyLocked( [System.Windows.Forms.Keys]::CapsLock )
  3. $numlock    = [System.Windows.Forms.Control]::IsKeyLocked( [System.Windows.Forms.Keys]::NumLock )
  4. $scrolllock = [System.Windows.Forms.Control]::IsKeyLocked( [System.Windows.Forms.Keys]::Scroll )
  5. $Insert     = [System.Windows.Forms.Control]::IsKeyLocked( [System.Windows.Forms.Keys]::Insert )
  6.  
  7. # or shorter, for CapsLock and NumLock only:
  8.  
  9. $capslock = [console]::CapsLock
  10. $numlock  = [console]::NumberLock

 

58. Show total physical memory in GB

  1. # Note that Get-ComputerInfo may take a while getting "all" available data
  2. [int]( ( Get-ComputerInfo ).CsTotalPhysicalMemory / 1GB )
  3.  
  4. # or, faster:
  5.  
  6. [int]( ( Get-CimInstance -ClassName Win32_PhysicalMemory | Measure-Object -Property Capacity -Sum ).Sum / 1GB )
  7.  
  8. # or:
  9.  
  10. $shell = New-Object -ComObject Shell.Application
  11. [int] ( $shell.GetSystemInformation( 'PhysicalMemoryInstalled' ) / 1GB )

 

59. Get window title

  1. $windowtitle = $Host.UI.RawUI.WindowTitle
  2.  
  3. # or:
  4.  
  5. $windowtitle = [console]::Title

 

60. Set window title

  1. $Host.UI.RawUI.WindowTitle = 'Test new window title'
  2.  
  3. # or:
  4.  
  5. [console]::Title = 'Test new window title'

 

61. Set foreground window

  1. # By window title (won't work on minimized windows):
  2. $wshShell = New-Object -ComObject WScript.Shell
  3. Start-Process -FilePath 'cmd.exe' -ArgumentList '/k title Test WScript.Shell.AppActivate' # open a test window
  4. pause # just to make sure the freshly opened window loses focus
  5. # AppActivate sets focus to a window with matching title
  6. # WARNING: unlike in VBScript, in PowerShell WScript.Shell.AppActivate will always return false
  7. [void]$wshShell.AppActivate( 'Test WScript.Shell.AppActivate' )
  8.  
  9. # or:
  10.  
  11. Add-Type -AssemblyName Microsoft.VisualBasic
  12. Start-Process -FilePath 'cmd.exe' -ArgumentList '/k title Test Microsoft.VisualBasic.AppActivate' # open a test window
  13. pause # just to make sure the freshly opened window loses focus
  14. [Microsoft.VisualBasic.Interaction]::AppActivate( 'Test Microsoft.VisualBasic.AppActivate' )
  15.  
  16. # or by process name:
  17.  
  18. $def = @"
  19. [DllImport( "user32.dll" )]
  20. [return: MarshalAs( UnmanagedType.Bool )]
  21. public static extern bool SetForegroundWindow( IntPtr hWnd );
  22. "@
  23. Add-Type -Namespace NativeMethods -Name User32Dll -MemberDefinition $def -ReferencedAssemblies System.Runtime.InteropServices
  24. [NativeMethods.User32Dll]::SetForegroundWindow( ( Get-Process -Name 'cmd' | Select-Object -First 1 ).MainWindowHandle )

 

62. Hide the console window

  1. # Hide console window by Anthony on StackOverflow.com
  2. # http://stackoverflow.com/a/15079092
  3. $def = @'
  4. public static void ShowConsoleWindow( int state )
  5. {
  6. 	var handle = GetConsoleWindow( );
  7. 	ShowWindow( handle, state );
  8. }
  9.  
  10. [DllImport( "kernel32.dll" )]
  11. static extern IntPtr GetConsoleWindow( );
  12.  
  13. [DllImport( "user32.dll" )]
  14. static extern bool ShowWindow( IntPtr hWnd, int nCmdShow );
  15. '@
  16.  
  17. $hideconsole = Add-Type -MemberDefinition $def -Name Hide -Namespace HideConsole -ReferencedAssemblies System.Runtime.InteropServices -PassThru
  18. $hideconsole::ShowConsoleWindow( 0 ) # 0 to hide the console
  19.  
  20. Start-Sleep -Seconds 3 # Wait 3 seconds before restoring the window again
  21.  
  22. $hideconsole::ShowConsoleWindow( 5 ) # 5 to restore the console

 

Check out my Show-Console cmdlet.

63. Hide window of new process

  1. Start-Process -FilePath yourprog.exe -WindowStyle Hidden

 

64. Send keystrokes to a window

  1. # Source: https://superuser.com/a/1250038
  2. $wshShell = New-Object -ComObject WScript.Shell
  3. Start-Process -FilePath 'cmd.exe' -ArgumentList '/k title Test WScript.Shell.SendKeys'
  4. pause # just to make sure the freshly opened window loses focus
  5. # AppActivate sets focus to a window with matching title, so it can receive keystrokes sent by SendKeys.
  6. # WARNING: unlike in VBScript, in PowerShell AppActivate will always return false.
  7. [void]$wshShell.AppActivate( 'Test WScript.Shell.SendKeys' )
  8. Start-Sleep -Seconds 1
  9. $wshShell.SendKeys( 'exit' )
  10. Start-Sleep -Seconds 1
  11. $wshShell.SendKeys( '{ENTER}' )
  12.  
  13. # or:
  14.  
  15. Add-Type -AssemblyName Microsoft.VisualBasic
  16. Add-Type -AssemblyName System.Windows.Forms
  17. Start-Process -FilePath 'cmd.exe' -ArgumentList '/k title Test Microsoft.VisualBasic.SendKeys'
  18. pause # just to make sure the freshly opened window loses focus
  19. [Microsoft.VisualBasic.Interaction]::AppActivate( 'Test Microsoft.VisualBasic.SendKeys' )
  20. Start-Sleep -Seconds 1
  21. [System.Windows.Forms.SendKeys]::SendWait( 'exit' )
  22. Start-Sleep -Seconds 1
  23. [System.Windows.Forms.SendKeys]::SendWait( '{ENTER}' )

 

Check out this list of special characters for SendKeys

65. Get commandline of a running process

  1. $process = 'rundll32.exe'
  2. Get-CimInstance -ClassName Win32_Process -Filter "Name='$process'" | ForEach-Object { $_.CommandLine }

 

66. Sort by string vs. sort by number

  1. $months = "9","12","3","7","5","6","4","8","1","10","11","2"
  2. Write-Host "`nSort as strings:"
  3. $months | Sort-Object # returns 1,10,11,12,2,3,4,5,6,7,8,9
  4. Write-Host"`nSort as numbers:"
  5. $months | Sort-Object { [int]$_ } # returns 1,2,3,4,5,6,7,8,9,10,11,12

 

67. Simple WMI Query

  1. if ( $PSVersionTable.PSVersion.Major -gt 4 ) {
  2. 	# PowerShell 3 and later
  3. 	$instances = Get-CimInstance -ClassName MSFT_PhysicalDisk -Namespace root/Microsoft/Windows/Storage
  4. } else {
  5. 	# PowerShell 5 and older
  6. 	$instances = Get-WMIObject -Query "SELECT * FROM MSFT_PhysicalDisk" -Namespace "root/Microsoft/Windows/Storage"
  7. }
  8. foreach ( $item in $instances ) {
  9. 	Write-Host ( "Model   : {0}" -f $item.Model )
  10. 	Write-Host ( "Size    : {0} GB" -f [int]( $item.Size / 1GB ) )
  11. 	# or: Write-Host ( "Size    : {0:F0} GB" -f ( $item.Size / 1GB ) )
  12. 	Write-Host ( "BusType : {0}" -f $item.BusType )
  13. 	Write-Host
  14. }

 

68. Get cryptographic file hash

  1. $hash = Get-FileHash -Path d:\folder\file.ext -Algorithm SHA256 #MD5, SHA1, SHA256, SHA384 or SHA512

 

69. Get AntiVirus product name(s) and definitions timestamp

  1. Get-CimInstance -Namespace root\SecurityCenter2 -Class AntiVirusProduct | Select-Object -Property displayname,timestamp

 

70. Encode to and decode from B64

  1. $originaltext = "Original unencoded text"
  2. "Original text : {0}" -f $originaltext
  3. $encodedtext = [System.Convert]::ToBase64String( [System.Text.Encoding]::Unicode.GetBytes( $originaltext ) )
  4. "Encoded text  : {0}" -f $encodedtext
  5. $decodedtext = [System.Text.Encoding]::Unicode.GetString( [System.Convert]::FromBase64String( $encodedtext ) )
  6. "Decoded text  : {0}" -f $decodedtext

 

71. Convert an image

  1. Add-Type -AssemblyName System.Drawing
  2. $inputfile  = 'd:\folder\image.jpg'
  3. $outputfile = $inputfile -replace '\.jpe?g$', '.png'
  4. # Valid ImageFormat values can be found with the command
  5. # [System.Drawing.Imaging.ImageFormat].DeclaredProperties.Name
  6. # or at https://docs.microsoft.com/en-us/dotnet/api/system.drawing.imaging.imageformat
  7. $outputformat = [System.Drawing.Imaging.ImageFormat]::Png
  8. $bitmap       = New-Object -TypeName System.Drawing.Bitmap -ArgumentList $inputfile
  9. $bitmap.Save( $outputfile, $outputformat )

 

72. Resize (and optionally convert) an image

  1. Add-Type -AssemblyName System.Drawing
  2. $inputfile       = 'd:\folder\testimage.tif'
  3. $outputfile      = $inputfile -replace '\.[^\.\\]+$', '.resized50percent.jpg'
  4. $scalepercentage = 50
  5. # Valid ImageFormat values can be found with the command
  6. # [System.Drawing.Imaging.ImageFormat].DeclaredProperties.Name
  7. # or at https://docs.microsoft.com/en-us/dotnet/api/system.drawing.imaging.imageformat
  8. $outputformat = [System.Drawing.Imaging.ImageFormat]::Jpeg
  9. $bitmap       = New-Object -TypeName System.Drawing.Bitmap -ArgumentList $inputfile
  10. "Bitmap size BEFORE   {0}x{1}" -f $bitmap.Width, $bitmap.Height
  11. $newwidth     = [int]( $bitmap.Width  * $scalepercentage / 100 )
  12. $newheight    = [int]( $bitmap.Height * $scalepercentage / 100 )
  13. $resizedimage = New-Object -TypeName System.Drawing.Bitmap -ArgumentList $newwidth,$newheight
  14. [System.Drawing.Graphics]$graphic = [System.Drawing.Graphics]::FromImage( $resizedimage )
  15. $graphic.DrawImage( $bitmap, 0, 0, $newwidth, $newheight )
  16. $graphic.Dispose( )
  17. $resizedimage.Save( $outputfile, $outputformat )
  18. "Bitmap size AFTER    {0}x{1}" -f $resizedimage.Width, $resizedimage.Height

 

73. Rotate (and optionally convert) an image

  1. Add-Type -AssemblyName System.Drawing
  2. $inputfile  = 'd:\folder\testimage.tif'
  3. $outputfile = $inputfile -replace '\.[^\.\\]+$', '.rotated90degrees.jpg'
  4. # Valid ImageFormat values can be found with the command
  5. # [System.Drawing.Imaging.ImageFormat].DeclaredProperties.Name
  6. # or at https://docs.microsoft.com/en-us/dotnet/api/system.drawing.imaging.imageformat
  7. $outputformat = [System.Drawing.Imaging.ImageFormat]::Jpeg
  8. $bitmap       = New-Object -TypeName System.Drawing.Bitmap -ArgumentList $inputfile
  9. # valid RotateFlipType values can be found with the command
  10. # [enum]::GetNames( [System.Drawing.RotateFlipType] )
  11. # or at https://docs.microsoft.com/en-us/dotnet/api/system.drawing.rotatefliptype
  12. $bitmap.RotateFlip( [System.Drawing.RotateFlipType]::Rotate90FlipNone )
  13. $bitmap.Save( $outputfile, $outputformat ) # Note: output file size may be considerably larger than expected

 

74. Generate an EAN-13 barcode image

  1. # This script requires EAN-13 font made available by Fontpalace.com:
  2. # http://www.fontpalace.com/font-download/EAN-13/
  3. # You can modify this script to generate any text in images, in which case you probably won't need the EAN-13 font
  4. Add-Type -AssemblyName System.Drawing
  5.  
  6. # specify EAN-13 font
  7. $font = New-Object -TypeName System.Drawing.Font( 'EAN-13', 48 )
  8. # test if EAN-13 font is installed
  9. if ( $font.Name -ne 'EAN-13' ) {
  10. 	$errormessage  = "`n `n`tThis script requires the `"EAN-13`" font made available by Fontpalace.com:"
  11. 	$errormessage += "`n`thttp://www.fontpalace.com/font-download/EAN-13/`n `n"
  12. 	Write-Error $errormessage -ErrorAction 'Stop'
  13. }
  14.  
  15. $text            = $( Get-Date -Format 'yyyyMMddHHmmss' ).Substring( 0, 13 ) # or any other 13-digit number
  16. # You can list all available text colors with the command: [System.Drawing.Brushes].DeclaredProperties.Name
  17. $textcolor       = [System.Drawing.Brushes]::Black
  18. # You can list all available background colors with the command: [enum]::GetNames( [System.Drawing.KnownColor] )
  19. $backgroundcolor = [System.Drawing.Color]::White
  20. $outputfile      = ( "D:\barcode{0}.jpg" -f $text )
  21. # You can list available output formats with the command: [System.Drawing.Imaging.ImageFormat].DeclaredFields.Name
  22. $outputformat    = [System.Drawing.Imaging.ImageFormat]::Jpeg
  23.  
  24. $bitmap     = New-Object -TypeName System.Drawing.Bitmap -ArgumentList 1,1
  25. $graphic    = [System.Drawing.Graphics]::FromImage( $bitmap );
  26. $stringsize = $graphic.MeasureString( $text, $font ) # calculate required image size
  27. $bitmap     = New-Object -TypeName System.Drawing.Bitmap -ArgumentList $bitmap,$stringsize.Width,$stringsize.Height
  28. $graphic    = [System.Drawing.Graphics]::FromImage( $bitmap )
  29. $graphic.Clear( $backgroundcolor )
  30. $graphic.DrawString( $text, $font, $textcolor, 0, 0 )
  31. $font.Dispose( )
  32. $graphic.Flush( )
  33. $graphic.Dispose( )
  34. $bitmap.Save( $outputfile, $outputformat )
  35.  
  36. # Open the image we just created
  37. Start-Process -FilePath $outputfile

 

And this is what the result of the previous code will look like:

Example of generated barcode image

75. Take a screenshot

  1. # Based on C# code by Ali Hamdar (http://alihamdar.com/)
  2. # http://social.msdn.microsoft.com/Forums/en/csharpgeneral/thread/79efecc4-fa6d-4078-afe4-bb1379bb968b
  3.  
  4. $outputfile = 'D:\test.jpg'
  5. $imagetype  = 'jpeg' # bmp, emf, gif, jpeg, png, tiff, wmf
  6.  
  7. Add-Type -AssemblyName System.Windows.Forms
  8. Add-Type -AssemblyName System.Drawing
  9.  
  10. # Default values for full screen
  11. $width  = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds.Width
  12. $height = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds.Height
  13. $top    = 0
  14. $left   = 0
  15.  
  16. [System.Drawing.Bitmap]$printscreen = New-Object System.Drawing.Bitmap( $width, $height )
  17. [System.Drawing.Graphics]$graphics  = [System.Drawing.Graphics]::FromImage( $printscreen )
  18. $graphics.CopyFromScreen( $top, $left, 0, 0, $printscreen.Size )
  19. $printscreen.Save( $outputfile, $imagetype ) # will overwrite existing file without prompt for confirmation
  20.  
  21. Start-Process -FilePath $outputfile # open the screenshot we just saved

 

76. Get the current wallpaper path

  1. # Windows 10:
  2. # Source: https://gist.github.com/winhelponline/4dc635770d5b123f6c1a719326037880
  3. $TIC = ( Get-ItemProperty 'HKCU:\Control Panel\Desktop' TranscodedImageCache -ErrorAction Stop ).TranscodedImageCache
  4. [System.Text.Encoding]::Unicode.GetString( $TIC ) -replace '(.+)([A-Z]:[0-9a-zA-Z\\])+','$2'
  5.  
  6. # Windows 7 with PowerShell 5:
  7. # Source: https://quickbytesstuff.blogspot.com/2015/11/powershell-check-wallpaper-location.html
  8. ( Get-WmiObject -Class 'Win32_Desktop' ).Wallpaper

 

77. Check if a mouse is available

  1. $hasmouse = [System.Windows.Forms.SystemInformation]::MousePresent
  2. if ( $hasmouse )
  3. {
  4. 	Write-Host "At least " -NoNewline
  5. 	Write-Host "1" -ForegroundColor Green -NoNewline
  6. 	Write-Host " mouse available"
  7. }
  8. else
  9. {
  10. 	Write-Host "No" -ForegroundColor Red -NoNewline
  11. 	Write-Host " mouse available"
  12. }

 

78. Check if mouse buttons are swapped

  1. Add-Type -AssemblyName System.Windows.Forms
  2. Write-Host 'Primary mouse button: ' -NoNewline
  3. if ( [System.Windows.Forms.SystemInformation]::MouseButtonsSwapped ) {
  4. 	Write-Host 'right'
  5. } else {
  6. 	Write-Host 'left'
  7. }
  8.  
  9. # Open mouse button settings (Windows 8..11)
  10. Start-Process "ms-settings:mousetouchpad"

 

79. Check if computer is touch-enabled

  1. # Using WMI, relies on a description which is not the most reliable way:
  2. "Touch enabled: {0}" -f ( ( Get-CimInstance -ClassName Win32_PnPEntity | Where-Object { $_.Description -match 'touch' } ).Count -gt 0 )
  3.  
  4. # or using P/Invoke:
  5. $code = @'
  6. [DllImport( "user32.dll" )]
  7. public static extern int GetSystemMetrics( int smIndex );
  8. '@
  9. Add-Type -Namespace NativeMethods -Name User32Dll -MemberDefinition $code -ReferencedAssemblies System.Runtime.InteropServices
  10. "Touch enabled: {0}" -f ( [NativeMethods.User32Dll]::GetSystemMetrics( 95 ) -gt 0 )

 

80. Check if computer is Bluetooth-enabled

  1. [boolean] ( @( Get-CimInstance -ClassName Win32_PnPEntity -Filter 'PNPClass="Bluetooth"' ).Count -gt 0 )

 

81. Get the default printer

  1. # Use WMI:
  2. Get-CimInstance -ClassName Win32_Printer -Filter "Default=TRUE"
  3.  
  4. # or read its name from the registry:
  5. ( Get-ItemProperty -Path 'HKCU:Software\Microsoft\Windows NT\CurrentVersion\Windows' ).Device.Split( ',' )[0]
  6.  
  7. # or use System.Drawing.Printing:
  8. Add-Type -AssemblyName System.Drawing
  9. $printer = New-Object -TypeName System.Drawing.Printing.PrinterSettings
  10. Get-Printer | ForEach-Object {
  11. 	$printer.PrinterName = $_.Name
  12. 	if ( $printer.IsDefaultPrinter ) {
  13. 		"Default printer: {0}" -f $_.Name
  14. 	}
  15. }
  16.  
  17. # or shorter:
  18.  
  19. Add-Type -AssemblyName System.Drawing
  20. "Default printer: {0}" -f ( New-Object -TypeName System.Drawing.Printing.PrinterSettings | Where-Object { $_.IsDefaultPrinter } ).PrinterName

 

82. Check if a printer can print duplex

  1. Add-Type -AssemblyName System.Drawing
  2. $printersettings = New-Object -TypeName System.Drawing.Printing.PrinterSettings
  3. Get-Printer | ForEach-Object {
  4. 	$printersettings.PrinterName = $_.Name
  5. 	$printersettings.CanDuplex
  6. }
  7.  
  8. # or, using WMI (may fail on non-English systems):
  9. Get-CimInstance -ClassName Win32_Printer `
  10. | Select-Object -Property CapabilityDescriptions,Name `
  11. | Where-Object { $_.CapabilityDescriptions -match 'Duplex' }
  12.  
  13. # or, if duplex printing requires a duplex unit:
  14. Get-Printer | ForEach-Object {
  15. 	$printername = $_.Name
  16. 	Get-PrinterProperty -PrinterName $printername `
  17. 	| Where-Object { $_.PropertyName -eq 'Config:DuplexUnit' -and $_.Value -eq 'Installed' } `
  18. 	| ForEach-Object { "Printer `"$printername`" has a duplex unit installed" }
  19. }

 

83. Windows 10: check who manages the default printer

  1. $regKey = "HKCU:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\"
  2. $LegacyDefaultPrinterMode = ( Get-ItemProperty $regKey ).LegacyDefaultPrinterMode
  3. if ( $LegacyDefaultPrinterMode -eq 1 ) {
  4. 	Write-Host 'You manage your default printer yourself'
  5. } else {
  6. 	Write-Host 'You let Windows manage your default printer for you'
  7. }

 

84. Windows 10: manage the default printer yourself

  1. $regKey = "HKCU:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\"
  2. Set-ItemProperty -Path $regKey -Name 'LegacyDefaultPrinterMode' -Value 1

 

85. Print a file

  1. # Plain text files:
  2. Get-Content -Path 'd:\folder\mytextfile.txt' | Out-Printer # print to default printer
  3. Get-Content -Path 'd:\folder\mytextfile.txt' | Out-Printer -Name 'Microsoft Print to PDF' # print to alternative printer
  4. Start-Process -FilePath 'd:\folder\mytextfile.txt' -Verb Print # print to default printer
  5.  
  6. # Other file types with associated print command:
  7. Start-Process -FilePath 'd:\folder\mypdffile.pdf' -Verb Print # print to default printer

 

86. List local users whose password never expires

  1. Get-LocalUser | Where-Object { !$_.PasswordExpires }
  2.  
  3. # or use WMI, which returns more properties:
  4.  
  5. Get-CimInstance -ClassName Win32_UserAccount | Where-Object { !$_.PasswordExpires }
  6.  
  7. # or shorter:
  8.  
  9. Get-CimInstance -ClassName Win32_UserAccount -Filter 'PasswordExpires=FALSE'

 

87. Run an existing Scheduled Task

  1. # StartComponentCleanup job cleans up WinSxS directory; admin privileges required
  2. $task = Start-ScheduledTask -TaskPath '\Microsoft\Windows\Servicing\' -TaskName 'StartComponentCleanup' -AsJob
  3. Start-Sleep -Seconds 1 # wait 1 second
  4. $task.Progress # then check its progress

 

88. Check if floppy drives are available

  1. # assuming that floppy drives will only have driveletter A: and B: which may in rare cases not be true:
  2. Get-Volume | Where-Object { $_.DriveType -eq 'Removable' -and $_.DriveLetter -lt 'C' }
  3.  
  4. # WMI is more reliable and returns more information:
  5. Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType = 2 And MediaType > 1 And MediaType != 11 And MediaType !=12"
  6.  
  7. # slightly simpler code, but MUCH slower if there are network drives:
  8. Get-CimInstance -ClassName Win32_LogicalDisk -Filter "MediaType > 1 And MediaType != 11 And MediaType !=12"

 

89. Check if a scanner is available

  1. $wia = New-Object -ComObject WIA.DeviceManager
  2. ( $wia.DeviceInfos.Count -gt 0 )

 

90. List scanner properties

  1. $wia = New-Object -ComObject WIA.DeviceManager
  2. $wia.DeviceInfos | ForEach-Object {
  3. 	$scanner = $_.Connect( )
  4. 	$scanner.Properties | Select-Object -Property Name,Value
  5. }

 

91. Scan and save a document

  1. # Based on code by Vadim Kantorov: https://stackoverflow.com/a/28422467
  2. # WIA FormatID constants: https://docs.microsoft.com/en-us/previous-versions/windows/desktop/wiaaut/-wiaaut-consts-formatid
  3. Set-Variable wiaFormatBMP  -Option Constant -Value '{B96B3CAB-0728-11D3-9D7B-0000F81EF32E}'
  4. Set-Variable wiaFormatPNG  -Option Constant -Value '{B96B3CAF-0728-11D3-9D7B-0000F81EF32E}'
  5. Set-Variable wiaFormatGIF  -Option Constant -Value '{B96B3CB0-0728-11D3-9D7B-0000F81EF32E}'
  6. Set-Variable wiaFormatJPEG -Option Constant -Value '{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}'
  7. Set-Variable wiaFormatTIFF -Option Constant -Value '{B96B3CB1-0728-11D3-9D7B-0000F81EF32E}'
  8.  
  9. $deviceManager = new-object -COMObject WIA.DeviceManager
  10. $device = $deviceManager.DeviceInfos.Item( 1 ).Connect( )
  11. $device.Items | ForEach-Object {
  12. 	$image = $_.Transfer( $wiaFormatPNG )
  13. }
  14.  
  15. # Just in case the scanner doesn't support saving in PNG format:
  16. if ( $image.FormatID -ne $wiaFormatPNG ) {
  17. 	$imageProcess = New-Object -COMObject WIA.ImageProcess
  18. 	$imageProcess.Filters.Add( $imageProcess.FilterInfos.Item( "Convert" ).FilterID )
  19. 	$imageProcess.Filters.Item( 1 ).Properties.Item( "FormatID" ).Value = $wiaFormatPNG
  20. 	$image = $imageProcess.Apply( $image )
  21. }
  22.  
  23. $image.SaveFile( "D:\test.png" )

 

92. Play an audio CD

  1. # The first script block is the "cleanest" way, as it will NOT throw an error if no CD is found:
  2. # Get all optical drives . . . . . . . . . . . . . . . . . . . with an audio CD loaded . . . . . just the first one
  3. Get-CimInstance -ClassName Win32_CDROMDrive | Where-Object { $_.VolumeName -EQ 'Audio CD' } | Select-Object -First 1 | ForEach-Object {
  4. 	# open the audio CD with the associated player
  5. 	Start-Process -FilePath $_.Drive -Verb Play
  6. }
  7.  
  8. # or without WMI (note that assuming index [0] instead of using Select-Object -First 1 will throw an error if no CD is found):
  9. # . . . . . All drives . . . . . . . . . . . . . select optical drives with an audio CD loaded . . . . . drive letter of the first matching drive
  10. $driveletter = ( Get-Volume | Where-Object { $_.DriveType -eq 'CD-ROM' -and $_.FileSystemLabel -eq 'Audio CD' } ).DriveLetter[0]
  11. Start-Process -FilePath "$driveletter`:" -Verb Play
  12.  
  13. # or the most simple one, though not 100% tamper-proof, and like the previous script block will throw an error if no CD is found:
  14. $driveletter = ( Get-Volume -FileSystemLabel 'Audio CD' ).DriveLetter[0]
  15. Start-Process -FilePath "$driveletter`:" -Verb Play

 

93. Eject all CDs

  1. # This script requires Windows Media Player
  2. $player = New-Object -ComObject WMPlayer.OCX
  3. 0..( $player.cdromCollection.count - 1 ) | ForEach-Object { $player.cdromCollection.Item($_).Eject( ) }

 

94. Check if Acrobat Reader is installed

  1. $acrobatreaderinstalled = ( [System.Type]::GetTypeFromProgID( "AcroPDF.PDF" ) -ne $null )

 

95. Check if Microsoft Raw Image Extension is installed

  1. # for all users, requires elevated privileges:
  2. $riainstalled = $( ( Get-AppxPackage -AllUsers ).Name -match "RawImageExtension" ) -ne $null
  3. # for current user, no elevated privileges required:
  4. $riainstalled = $( ( Get-AppxPackage ).Name -match "RawImageExtension" ) -ne $null

 

96. Check if Microsoft Office is installed

  1. $accessinstalled     = ( [System.Type]::GetTypeFromProgID( "Access.Application" )     -ne $null )
  2. $excelinstalled      = ( [System.Type]::GetTypeFromProgID( "Excel.Application" )      -ne $null )
  3. $msgraphinstalled    = ( [System.Type]::GetTypeFromProgID( "MSGraph.Application" )    -ne $null )
  4. $outlookinstalled    = ( [System.Type]::GetTypeFromProgID( "Outlook.Application" )    -ne $null )
  5. $powerpointinstalled = ( [System.Type]::GetTypeFromProgID( "PowerPoint.Application" ) -ne $null )
  6. $wordinstalled       = ( [System.Type]::GetTypeFromProgID( "Word.Application" )       -ne $null )

 

97. Check if OpenOffice or LibreOffice is installed

  1. # works for OpenOffice.org, Apache OpenOffice and LibreOffice
  2. $openofficeinstalled = ( [System.Type]::GetTypeFromProgID( "com.sun.star.ServiceManager" ) -ne $null )

 

98. Check if WordPerfect is installed

  1. $wordperfectinstalled = ( [System.Type]::GetTypeFromProgID( "WordPerfect.PerfectScript" ) -ne $null )

 

99. Read an Excel file (requires Excel)

  1. # Based on article by François-Xavier Cat
  2. # https://lazywinadmin.com/2014/03/powershell-read-excel-file-using-com.html
  3. $objExcel = New-Object -ComObject Excel.Application
  4. $workbook = $objExcel.Workbooks.Open( $excelfile ) # $excelfile must be specified
  5. $workbook.Sheets | ForEach-Object {
  6. 	if ( ![string]::IsNullOrEmpty( $_.Range( "A1" ).Text ) ) { # skip sheets with cell A1 empty
  7. 		Write-Host $_.Name # sheet name
  8. 		Write-Host ( "=" * $_.Name.Length ) # underline sheet name
  9. 		Write-Host
  10. 		for ( $row = 1; $row -le $_.UsedRange.Rows.Count; $row++ ) { # iterate through all rows in used range
  11. 			for ( $column = 1; $column -le $_.UsedRange.Columns.Count ; $column++ ) { # iterate through all columns in used range
  12. 				Write-Host ( "({0}{1})`t{2}" -f ( [char] ( $column + 64 ) ), $row, $_.Columns.Item( $column ).Rows.Item( $row ).Text ) # e.g. '(A4) content_of_cell_A4'
  13. 			}
  14. 			Write-Host # blank line between rows
  15. 		}
  16. 	}
  17. }
  18. [void] $workbook.Close( ) # close Excel file
  19. [void] $objExcel.Quit( ) # should close Excel application but may not always do so

 

100. Read an Excel file without Excel

  1. # Requires Microsoft Access Database Engine 2016 Redistributable:
  2. # https://www.microsoft.com/en-us/download/details.aspx?id=54920
  3.  
  4. Set-Variable adOpenStatic -Option Constant -Value 3
  5.  
  6. $excelfile = 'd:\folder\excelfile.xlsx'
  7. $sheet = 'Sheet1'
  8. $range = 'A1:D14'
  9.  
  10. $connectstring = "Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};DBQ=$excelfile;Extended Properties=`"Excel 12.0 Xml;IMEX=1;`""
  11. $excel = New-Object -ComObject ADODB.Connection
  12. $excel.Open( $connectstring )
  13. $recordset = New-Object -ComObject ADODB.RecordSet
  14. $recordset.Open( ( "Select * from [{0}`${1}]" -f $sheet, $range ), $excel, $adOpenStatic )
  15. $recordset.MoveFirst( )
  16. # Determine the required width of the first column
  17. $column1width = 1
  18. 0..3 | ForEach-Object { $column1width = [System.Math]::Max( $column1width, $recordset.Fields.Item( $_ ).Name.length ) }
  19. $recordset.MoveFirst( )
  20. while ( !$recordset.EOF ) {
  21. 	0..3 | ForEach-Object { Write-Host ( "{0,-$column1width}    {1}" -f $recordset.Fields.Item( $_ ).Name, $recordset.Fields.Item( $_ ).Value ) }
  22. 	Write-Host
  23. 	$recordset.MoveNext( )
  24. }
  25. $recordset.Close( )
  26. $excel.Close( )

 

101. Print a Word document to the default printer (requires Word)

  1. $objWord = New-Object -ComObject Word.Application
  2. [void] $objWord.Documents.Open( "$wordfile", $false, $true ) # $wordfile must be specified
  3. $objWord.ActiveDocument.PrintOut( )
  4. $objWord.ActiveDocument.Close( $false )
  5. $objWord.Quit( )
  6.  
  7. # or:
  8.  
  9. Start-Process -Filepath "$wordfile" -Verb Print # $wordfile must be specified

 

102. Print a Word document to another printer (requires Word)

  1. $objWord = New-Object -ComObject Word.Application
  2. $defaultprinter = $objWord.ActivePrinter
  3. $objWord.ActivePrinter = "$otherprinter" # $otherprinter must be specified
  4. [void] $objWord.Documents.Open( "$wordfile", $false, $true ) # $wordfile must be specified
  5. $objWord.ActiveDocument.PrintOut( )
  6. $objWord.ActiveDocument.Close( $false )
  7. $objWord.ActivePrinter = $defaultprinter
  8. $objWord.Quit( )

 

103. Open a Word document and save it as PDF (requires Word)

  1. # Output format constants: https://docs.microsoft.com/office/vba/api/word.wdsaveformat
  2. Set-Variable -Name 'wdFormatPDF'        -Option Constant -Value 17 -ErrorAction SilentlyContinue
  3. Set-Variable -Name 'wdDoNotSaveChanges' -Option Constant -Value  0 -ErrorAction SilentlyContinue
  4.  
  5. $wordfile  = 'D:\folder\wordfile.docx'
  6. $pdffile   = 'D:\folder\pdffile.pdf'
  7. $pdfformat = $wdFormatPDF
  8. $wordapp   = New-Object -ComObject Word.Application
  9. $wordapp.Documents.Open( $wordfile, $false, $true )
  10. $wordapp.Documents.Item( $wordfile ).Activate( )
  11. $wordapp.ActiveDocument.SaveAs( $pdffile, $pdfformat )
  12. $wordapp.ActiveDocument.Close( $wdDoNotSaveChanges )
  13. $wordapp.Quit( )

 

104. Open a Word document and save it in OpenOffice format (requires Word)

  1. # Output format constants: https://docs.microsoft.com/office/vba/api/word.wdsaveformat
  2. Set-Variable -Name 'wdFormatOpenDocumentText' -Option Constant -Value 23 -ErrorAction SilentlyContinue
  3. Set-Variable -Name 'wdDoNotSaveChanges'       -Option Constant -Value  0 -ErrorAction SilentlyContinue
  4.  
  5. $wordfile  = 'D:\folder\test.docx'
  6. $odtfile   = 'D:\folder\test.odt'
  7. $odtformat = $wdFormatOpenDocumentText
  8. $wordapp   = New-Object -ComObject Word.Application
  9. $wordapp.Documents.Open( $wordfile, $false, $true )
  10. $wordapp.Documents.Item( $wordfile ).Activate( )
  11. $wordapp.ActiveDocument.SaveAs( $odtfile, $odtformat )
  12. $wordapp.ActiveDocument.Close( $wdDoNotSaveChanges )
  13. $wordapp.Quit( ) # if you are sure no other documents are opened in Word

 

105. Open an OpenOffice text document and save it as PDF (requires OpenOffice and SDK)

  1. # Based on code by Ijacek:
  2. # https://forum.openoffice.org/en/forum/viewtopic.php?f=44&t=33643
  3. # and many experiments, and many searches on:
  4. # https://wiki.openoffice.org/wiki/Documentation/DevGuide/OpenOffice.org_Developers_Guide
  5. $inputDoc = 'D:\folder\oofile.odt'
  6. $outputPDF = 'D:\folder\oofile.pdf'
  7. if ( Test-Path -Path $outputPDF -PathType Leaf ) {
  8. 	Remove-Item -Path $outputPDF -Force
  9. }
  10. # convert file paths to URLs
  11. $inputURL = ( "file:///{0}" -f ( $inputDoc -replace '\\', '/' ) )
  12. $outputURL = ( "file:///{0}" -f ( $outputPDF -replace '\\', '/' ) )
  13. # set up OpenOffice automation environment
  14. [void][System.Reflection.Assembly]::LoadWithPartialName( 'cli_basetypes' )
  15. [void][System.Reflection.Assembly]::LoadWithPartialName( 'cli_cppuhelper' )
  16. [void][System.Reflection.Assembly]::LoadWithPartialName( 'cli_oootypes' )
  17. [void][System.Reflection.Assembly]::LoadWithPartialName( 'cli_ure' )
  18. [void][System.Reflection.Assembly]::LoadWithPartialName( 'cli_uretypes' )
  19. $localContext = [uno.util.Bootstrap]::bootstrap( )
  20. $multiComponentFactory = [unoidl.com.sun.star.uno.XComponentContext].getMethod( 'getServiceManager' ).invoke( $localContext, @( ) )
  21. $desktop = [unoidl.com.sun.star.lang.XMultiComponentFactory].getMethod( 'createInstanceWithContext' ).invoke( $multiComponentFactory, @( 'com.sun.star.frame.Desktop', $localContext ) )
  22. # set file open property Hidden
  23. $openHidden = New-Object unoidl.com.sun.star.beans.PropertyValue
  24. $openHidden.Name = "Hidden"
  25. $openHidden.Value = $true
  26. $openProperties = [unoidl.com.sun.star.beans.PropertyValue[]] @( [unoidl.com.sun.star.beans.PropertyValue] $openHidden )
  27. # open OpenOffice document
  28. $writer = [unoidl.com.sun.star.frame.XComponentLoader].getMethod( 'loadComponentFromURL' ).invoke( $desktop, @( $inputURL, '_default', 0, $openProperties ) )
  29. # set save as property to PDF
  30. $saveAsPDF = New-Object unoidl.com.sun.star.beans.PropertyValue
  31. $saveAsPDF.Name = 'FilterName'
  32. $saveAsPDF.Value = 'writer_pdf_Export'
  33. $storeProperties = [unoidl.com.sun.star.beans.PropertyValue[]] @( [unoidl.com.sun.star.beans.PropertyValue] $saveAsPDF )
  34. # save document as PDF
  35. [unoidl.com.sun.star.frame.XStorable].getMethod( 'storeToURL' ).invoke( $writer, @( $outputURL, $storeProperties ) )
  36. # close documents and program
  37. [void][unoidl.com.sun.star.frame.XDesktop].GetMethod( 'terminate' ).Invoke( $desktop, $null )
  38. # open the newly created PDF file, if it exists
  39. $success = Test-Path -Path $outputPDF -PathType Leaf
  40. if ( $success ) {
  41. 	Start-Process -FilePath $outputPDF
  42. }
  43. # return True if PDF was succesfully created
  44. $success

 

106. Extract plain text from a .DOCX Word file (no Office required)

  1. $docxfile = 'D:\folder\wordfile.docx'
  2. if ( -not ( Test-Path $docxfile -PathType Leaf ) ) {
  3. 	Write-Error ( "`n`tFile not found: `"{0}`"`n`n" -f $docxfile ) -ErrorAction 'Stop'
  4. }
  5. $docxext = [System.IO.Path]::GetExtension( $docxfile )
  6. if ( $docxext -ne '.docx' ) {
  7. 	Write-Error "`n`tThis script reads the text content from .DOCX files only`n`n" -ErrorAction 'Stop'
  8. }
  9. Copy-Item -Path $docxfile -Destination "$Env:Temp\~readdocx.zip" -Force # Copy Word file to Temp directory, renaming it to ZIP on the fly
  10. Expand-Archive -Path "$Env:Temp\~readdocx.zip" -DestinationPath "$Env:Temp\~readdocx" -Force # extract the temporary ZIP file
  11. Remove-Item -Path "$Env:Temp\~readdocx.zip" -Force # remove the temporary ZIP file
  12. $docxcontent = $( Get-Content -Path "$Env:Temp\~readdocx\word\document.xml" -Encoding UTF8 ) # read the file document.xml from the extracted ZIP
  13. Remove-Item -Path "$Env:Temp\~readdocx" -Recurse -Force # remove the extracted files
  14. $plaintext = ( $docxcontent -replace '<[^>]+.', '' ) # remove all tags from the XML's content
  15. $plaintext # show the result

 

107. Extract plain text from a .DOC Word file (no Office required)

  1. # Not as reliable as the code to extract plain text from .DOCX but it usually seems to work
  2. $docfile = 'D:\folder\wordfile.doc'
  3. if ( -not ( Test-Path $docfile -PathType Leaf ) ) {
  4. 	Write-Error ( "`n`tFile not found: `"{0}`"`n`n" -f $docfile ) -ErrorAction 'Stop'
  5. }
  6. $docext = [System.IO.Path]::GetExtension( $docfile )
  7. if ( $docext -ne '.doc' ) {
  8. 	Write-Error "`n`tThis script reads the text content from .DOC files only`n`n" -ErrorAction 'Stop'
  9. }
  10. $regex = New-Object -TypeName System.Text.RegularExpressions.Regex -ArgumentList '[^\000\015\367\377]{20,}'
  11. # Assuming the document contained enough text to beat the embedded control strings in length
  12. $plaintext = $( $regex.Matches( $( Get-Content -Path $docfile ) ) | Sort-Object { $_.Length } | Select-Object -Last 1 ).Value
  13. $plaintext

 

108. Extract plain text from an OpenOffice .ODT file (no OpenOffice required)

  1. $odtfile = 'D:\folder\openofficetextfile.odt'
  2. if ( -not ( Test-Path $odtfile -PathType Leaf ) ) {
  3. 	Write-Error ( "`n`tFile not found: `"{0}`"`n`n" -f $odtfile ) -ErrorAction 'Stop'
  4. }
  5. $odtext = [System.IO.Path]::GetExtension( $odtfile )
  6. if ( $odtext -ne '.odt' ) {
  7. 	Write-Error "`n`tThis script reads the text content from .ODT files only`n`n" -ErrorAction 'Stop'
  8. }
  9. # Copy OpenOffice file to Temp directory, renaming it to ZIP on the fly
  10. Copy-Item -Path $odtfile -Destination "$Env:Temp\~readodt.zip" -Force
  11. # extract the temporary ZIP file
  12. Expand-Archive -Path "$Env:Temp\~readodt.zip" -DestinationPath "$Env:Temp\~readodt" -Force
  13. # remove the temporary ZIP file
  14. Remove-Item -Path "$Env:Temp\~readodt.zip" -Force
  15. # read the file content.xml from the extracted ZIP
  16. $odtcontent = $( Get-Content -Path "$Env:Temp\~readodt\content.xml" -Encoding UTF8 )
  17. # remove the extracted files
  18. Remove-Item -Path "$Env:Temp\~readodt" -Recurse -Force
  19. # insert linefeeds after paragraphs, headers and list-items
  20. $plaintext = ( $odtcontent -replace '</text:(h|list-item|p)>', "`n`n" )
  21. # remove all tags from the XML's content
  22. $plaintext = ( $plaintext -replace '<[^>]+.', '' )
  23. # remove excess linefeeds
  24. $plaintext = ( $plaintext -replace "`n{3,}", "`n`n" )
  25. # show the result
  26. $plaintext

 

109. Extract plain text from a Rich Text Format (.RTF) file

  1. # Based on C# code to use hidden RichTextBox to convert RTF to plain text by Wendy Zang
  2. # https://social.msdn.microsoft.com/Forums/vstudio/en-US/6e56af9b-d7d3-49f3-9ec4-80edde3fe54b/reading-modifying-rtf-files?forum=csharpgeneral#a64345e9-cfcb-43be-ab18-c08fae02cb2a
  3. Add-Type -AssemblyName System.Windows.Forms
  4. $rtffile   = 'D:\folder\rtfdocument.rtf'
  5. $rtftext   = Get-Content -Path $rtffile
  6. $rtbox     = New-Object -TypeName System.Windows.Forms.RichTextBox
  7. $rtbox.Rtf = $rtftext
  8. $plaintext = $rtbox.Text
  9. $plaintext

 

110. Shutdown or reboot the computer

  1. # Reboot immediately:
  2. Restart-Computer -Force
  3. # or:
  4. Invoke-CimMethod -Query "SELECT * FROM Win32_OperatingSystem WHERE Primary=TRUE" -MethodName 'Reboot'
  5.  
  6. # Shutdown immediately:
  7. Stop-Computer -Force
  8. # or:
  9. Invoke-CimMethod -Query "SELECT * FROM Win32_OperatingSystem WHERE Primary=TRUE" -MethodName 'Shutdown'
  10.  
  11. # Kill all running processes immediately, resulting in a BSOD, NOT recommended:
  12. Stop-Process -ProcessName *

 

GUI

  1. Show the Desktop (minimize all windows)
  2. Rearrange all windows
  3. Select another window
  4. Open a directory in Explorer
  5. Empty the Recycle Bin (with prompt for confirmation)
  6. Open all empty CD-ROM drive trays and prompt for disk
  7. Change the mouse pointer
  8. Open Windows Update (or other) settings window
  9. Open Device Manager
  10. Open Sound settings
  11. Use System.Windows.Forms and System.Drawing to create GUIs
  12. Use Internet Explorer to create GUIs
  13. Copy a lot of files with progress bar
  14. Quick-and-dirty "Dropdown" selection
  15. Select and open a Shell Folder
  16. True Dropdown selection
  17. MessageBox
  18. InputBox
  19. Login dialog
  20. Select file dialog
  21. Browse for folder dialog
  22. Print dialog
  23. Select printer dialog
  24. Find Network Printer dialog
  25. Open the Printers folder
  26. Open the Network Neigborhood
  27. Open Network Places
  28. Open the Add/Remove Programs dialog
  29. Find Computer dialog
  30. Font select dialog
  31. Open the Fonts folder
  32. Date picker dialog
  33. Quick-and-dirty date picker alternative with Out-GridView
  34. Color picker dialog
  35. Embed base-64 encoded icon
  36. Show an icon in the System Tray (a.k.a. Notification Area)
  37. Open a Run dialog (same as Start Menu > Run)
  38. Open a Shutdown Windows dialog

1. Show the Desktop (minimize all windows)

  1. $shell = New-Object -ComObject Shell.Application
  2. $shell.MinimizeAll( ) # restore with $shell.UndoMinimizeALL( )
  3.  
  4. # or:
  5.  
  6. $shell.ToggleDesktop( ) # restore by running same command a second time (not very reliable)
  7.  
  8. # or:
  9.  
  10. # Source: Complete List of Windows 10 CLSID Key (GUID) Shortcuts by Shawn Brink
  11. # https://www.tenforums.com/tutorials/3123-clsid-key-guid-shortcuts-list-windows-10-a.html
  12. Start-Process -FilePath explorer.exe -ArgumentList 'shell:::{3080F90D-D7AD-11D9-BD98-0000947B0257}'
  13.  
  14. # or even shorter:
  15.  
  16. Start-Process -FilePath 'shell:::{3080F90D-D7AD-11D9-BD98-0000947B0257}'

 

2. Rearrange all windows

  1. $shell = New-Object -ComObject Shell.Application
  2. $shell.CascadeWindows( )
  3. Start-Sleep -Seconds 5
  4. $shell.TileHorizontally( )
  5. Start-Sleep -Seconds 5
  6. $shell.TileVertically( )

 

3. Select another window

  1. $shell = New-Object -ComObject Shell.Application
  2. $shell.WindowSwitcher( )

 

4. Open a directory in Explorer

  1. Start-Process -FilePath 'd:\'
  2.  
  3. # or:
  4.  
  5. Start-Process -FilePath 'explorer.exe' -ArgumentList 'd:\'
  6.  
  7. # or:
  8.  
  9. $shell = New-Object -ComObject Shell.Application
  10. $shell.Explore( 'd:\' )

 

5. Empty the Recycle Bin (with prompt for confirmation)

  1. # Unless you disabled it, you will still be prompted for confirmation
  2. Start-Process -FilePath 'shell:RecycleBinFolder' -Verb Empty
  3.  
  4. # or:
  5.  
  6. Start-Process -FilePath 'shell:::{645FF040-5081-101B-9F08-00AA002F954E}' -Verb Empty

 

And this is what the result of the previous code will look like:

Screenshot of Recycle Bin's prompt for confirmation

6. Open all empty CD-ROM drive trays and prompt for disk

  1. # All volumes . . . . . . . . . . . optical drives only . . . . no disk loaded . . . . . . . . . . . . . . . . . . . . . open drive . . . . . . . . . . show only the dialog
  2. Get-Volume | Where-Object { $_.DriveType -eq 'CD-ROM' -and -not $_.FileSystem } | ForEach-Object { Start-Process -FilePath ( "{0}:" -f $_.DriveLetter ) -WindowStyle Hidden }
  3.  
  4. # or:
  5.  
  6. # All CD-ROM drives . . . . . . . . . . . . . . . . . no disk loaded . . . . . . . . . . . . . . . . . . . . . . open drive . . . show only the dialog
  7. Get-CimInstance -ClassName Win32_CDROMDrive -Filter "MediaLoaded=FALSE" | ForEach-Object { Start-Process -FilePath $_.Drive -WindowStyle Hidden }

 

And this is what the result of the previous code will look like:

Screenshot of Prompt for Disk demo

7. Change the mouse pointer

  1. Add-Type -AssemblyName System.Windows.Forms
  2. [System.Windows.Forms.Application]::UseWaitCursor = $true
  3. Write-Host 'Move the mouse pointer please'
  4. Start-Sleep -Seconds 5
  5. [System.Windows.Forms.Application]::UseWaitCursor = $false
  6. Write-Host 'Now move the mouse pointer again, please'

 

8. Open Windows Update (or other) settings window

  1. # Open Windows Update settings; more URIs for specific settings can be found at
  2. # https://docs.microsoft.com/en-us/windows/uwp/launch-resume/launch-settings-app#ms-settings-uri-scheme-reference
  3. Start-Process "ms-settings:windowsupdate"

 

9. Open Device Manager

  1. Show-ControlPanelItem -Name 'Device Manager' # No longer works in PowerShell 7
  2.  
  3. # or, for all PowerShell versions:
  4.  
  5. # Source: Complete List of Windows 10 CLSID Key (GUID) Shortcuts by Shawn Brink
  6. # https://www.tenforums.com/tutorials/3123-clsid-key-guid-shortcuts-list-windows-10-a.html
  7. Start-Process -FilePath 'explorer.exe' -ArgumentList 'shell:::{74246bfc-4c96-11d0-abef-0020af6b0b7a}'
  8.  
  9. # or shorter:
  10.  
  11. Start-Process -FilePath 'shell:::{74246bfc-4c96-11d0-abef-0020af6b0b7a}'

 

10. Open Sound settings

  1. Start-Process -FilePath rundll32.exe -ArgumentList 'shell32.dll,Control_RunDLL mmsys.cpl'

 

And this is what the result of the previous code will look like:

Screenshot of Sound settings window

11. Use System.Windows.Forms and System.Drawing to create GUIs

  1. Add-Type -AssemblyName System.Windows.Forms
  2. Add-Type -AssemblyName System.Drawing
  3.  
  4. $form      = New-Object System.Windows.Forms.Form
  5. $form.Text = 'PowerShell GUI Demo'
  6. $form.Size = '400,240'
  7.  
  8. $label1          = New-Object System.Windows.Forms.Label
  9. $label1.Text     = 'Arial Arial Arial Arial Arial Arial Arial Arial Arial Arial Arial Arial Arial Arial Arial Arial Arial'
  10. $label1.Font     = New-Object System.Drawing.Font( 'Arial', 10 ) # This is the "official" way to specify a font
  11. $label1.Size     = New-Object System.Drawing.Size( 200, 40 )     # This is the "official" way to specify a size
  12. $label1.Location = New-Object System.Drawing.Point( 10, 25 )     # This is the "official" way to specify a location
  13. $form.Controls.Add( $label1 )
  14.  
  15. $label2          = New-Object System.Windows.Forms.Label
  16. $label2.Text     = 'Courier Courier Courier Courier Courier Courier Courier Courier Courier Courier Courier Courier Courier'
  17. $label2.Font     = 'Courier New,10' # This is an alternative way to specify a font
  18. $label2.Size     = '200, 40'        # This is an alternative way to specify a size
  19. $label2.Location = '10, 75'         # This is an alternative way to specify a location
  20. $form.Controls.Add( $label2 )
  21.  
  22. $buttonOK              = New-Object System.Windows.Forms.Button
  23. $buttonOK.Text         = 'OK'
  24. $buttonOK.DialogResult = 'OK' # This should usually not be required
  25. $buttonOK.Location     = '10, 150'
  26. $form.Controls.Add( $buttonOK )
  27.  
  28. $buttonCancel          = New-Object System.Windows.Forms.Button
  29. $buttonCancel.Text     = 'Cancel'
  30. $buttonCancel.Location = '120, 150'
  31. $form.Controls.Add( $buttonCancel )
  32.  
  33. $form.AcceptButton = $buttonOK # This should usually suffice to make the dialog return OK when OK is clicked
  34. $form.CancelButton = $buttonCancel
  35.  
  36. # Without [void] PowerShell will write the ShowDialog result (caption of the button clicked) to screen
  37. [void] $form.ShowDialog( )
  38.  
  39. # This is another way to get the form's ShowDialog result
  40. Write-Host $form.DialogResult

 

And this is what the result of the previous code will look like:

Screenshot of PowerShell GUI Demo

12. Use Internet Explorer to create GUIs

  1. # Using IE poses many challenges, use of System.Windows.Forms is preferred.
  2. # This script is derived from a VBScript version, and simplified; for details see:
  3. # https://www.robvanderwoude.com/vbstech_ui_password.php#InternetExplorer
  4. $password = ''
  5. $screen = Get-CimInstance -ClassName Win32_DesktopMonitor # used to center dialog on screen
  6. $html  = @"
  7. <div style="text-align: center;">
  8. <p>Please enter your password:</p>
  9. <p><input type="password" size="20" name="Password" id="Password" onkeyup="if(event.keyCode==13){document.all.OKButton.click();}" /></p>
  10. <p><input type="hidden" id="OK" name="OK" value="0" />
  11. <input type="submit" value=" OK " id="OKButton" onclick="document.all.OK.value=1;" /></p>
  12. </div>
  13. "@
  14. # open IE
  15. $ie = New-Object -ComObject 'InternetExplorer.Application'
  16. $ie.Navigate2( 'about:blank' )
  17. $ie.AddressBar = $false
  18. $ie.Resizable = $false
  19. $ie.StatusBar = $false
  20. $ie.ToolBar = $false
  21. $ie.Width = 320
  22. $ie.Height = 180
  23. $ie.Document.Title = 'Please enter password:'
  24. $ie.Document.body.innerHTML = $html
  25. # center dialog on screen
  26. $ie.Left = [int]( ( $screen.ScreenWidth - $ie.Width ) / 2 )
  27. $ie.Top = [int]( ( $screen.ScreenHeight - $ie.Height ) / 2 )
  28. $ie.Visible = $true
  29. $oldErrorActionPreference = $ErrorActionPreference
  30. $ErrorActionPreference = 'SilentlyContinue'
  31. # wait until OK is clicked or Enter is pressed
  32. do {
  33. 	Start-Sleep -Milliseconds 200
  34. } while ( ( $ie.Document.all | Where-Object -Property 'Name' -EQ 'OK' ).Value -eq 0 )
  35. $password = ( $ie.Document.all | Where-Object -Property 'IHTMLElement_id' -EQ 'Password' ).IHTMLInputTextElement_value
  36. # close IE
  37. $ie.Quit( )
  38. $ErrorActionPreference = $oldErrorActionPreference
  39. $password

 

And this is what the result of the previous code will look like:

Screenshot of PowerShell Internet Explorer GUI Demo

13. Copy a lot of files with progress bar

  1. # https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/file-system/how-to-provide-a-progress-dialog-box-for-file-operations
  2. Add-Type -AssemblyName Microsoft.VisualBasic
  3. $sourcePath = "$Env:windir\winSxS"
  4. $destinationPath = "$Env:Temp\test"
  5. $options = [Microsoft.VisualBasic.FileIO.UIOption]::AllDialogs
  6. [Microsoft.VisualBasic.FileIO.FileSystem]::CopyDirectory( $sourcePath, $destinationPath, $options )
  7. # Uncomment the next line to remove the files we copied for this demo
  8. #Remove-Item "$env:Temp\test\" -Force

 

And this is what the result of the previous code will look like:

Screenshot of PowerShell progress bar demo

14. Quick-and-dirty "Dropdown" selection

  1. # source: "Creating a GUI Using Out-GridView in PowerShell" by Boe Prox
  2. # https://mcpmag.com/articles/2016/02/17/creating-a-gui-using-out-gridview.aspx
  3. @( 'MyDesktop', 'MyLaptop', 'YourDesktop', 'Yourlaptop' ) | Out-GridView -PassThru -Title 'Select your favorite computer'

 

And this is what the result of the previous code will look like:

Screenshot of PowerShell GridView demo

15. Select and open a Shell Folder

  1. # Source: "Shell folders: the best-kept Windows time saving secret" by Mike Williams
  2. # https://www.techradar.com/news/computing/pc/shell-folders-the-best-kept-windows-time-saving-secret-464668
  3. $registrypath = 'HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\explorer\FolderDescriptions'
  4. $shellfolders = $( Get-ChildItem -Path $registrypath | Get-ItemProperty | Select-Object -Property Name,ParsingName -ErrorAction Ignore | Sort-Object { $_.Name } )
  5. $shellfolders | Out-GridView -Title 'Shell Folders' -PassThru | ForEach-Object { Start-Process -FilePath $( "shell:{0}" -f $_.Name ) }

 

And this is what the result of previous code will look like:

Screenshot of Shell Folders list in GridView

16. True Dropdown selection

  1. Add-Type -AssemblyName System.Windows.Forms
  2. Add-Type -AssemblyName System.Drawing
  3.  
  4. $form = New-Object -TypeName System.Windows.Forms.Form
  5. $form.Text = 'Select your favorite computer'
  6. $form.Size = '400, 200'
  7.  
  8. $list = @( 'My Desktop'; 'My Laptop'; 'Your Desktop'; 'Your Laptop' )
  9. $Script:selectedvalue = 'My Laptop'
  10.  
  11. $dropdown = New-Object -TypeName System.Windows.Forms.ComboBox
  12. $dropdown.Items.AddRange( $list )
  13. $dropdown.SelectedIndex = 1
  14. $dropdown.Width = '200'
  15. $dropdown.Location = New-Object System.Drawing.Point( [int]( ( $form.Width - $dropdown.Width ) / 2 ), 25 )
  16. $form.Controls.Add( $dropdown )
  17.  
  18. $buttonOK_Click = {
  19. 	$Script:selectedvalue = $dropdown.Text
  20. 	$form.DialogResult = 'OK'
  21. 	$form.Close( )
  22. }
  23.  
  24. $buttonOK = New-Object System.Windows.Forms.Button
  25. $buttonOK.Text = 'OK'
  26. $buttonOK.Location = New-Object System.Drawing.Point( [int]( ( $form.Width / 2 ) - 5 - $buttonOK.Width ), 100 )
  27. $buttonOK.Add_Click( $buttonOK_Click )
  28. $form.Controls.Add( $buttonOK )
  29. $form.AcceptButton = $buttonOK # pressing Enter assumes OK
  30.  
  31. $buttonCancel_Click = {
  32. 	$form.DialogResult = 'Cancel'
  33. 	$form.Close( )
  34. }
  35.  
  36. $buttonCancel = New-Object System.Windows.Forms.Button
  37. $buttonCancel.Text = 'Cancel'
  38. $buttonCancel.Location = New-Object System.Drawing.Point( [int]( ( $form.Width / 2 ) + 5 ), 100 )
  39. $buttonCancel.Add_Click( $buttonCancel_Click )
  40. $form.Controls.Add( $buttonCancel )
  41. $form.CancelButton = $buttonCancel # pressing Esc assumes Cancel
  42.  
  43. $result = $form.ShowDialog( )
  44.  
  45. if ( $result -eq 'OK' ) {
  46. 	$Script:selectedvalue
  47. }

 

And this is what the result of the previous code will look like:

Screenshot of PowerShell DropDown demo

Screenshot of PowerShell DropDown demo

17. MessageBox

  1. Add-Type -AssemblyName System.Windows.Forms
  2. # message is mandatory; title, button and icon are optional
  3. # message with OK only
  4. [void] [System.Windows.Forms.MessageBox]::Show( "Message", "Title", "OK", "Information" )
  5. # answer required
  6. $answer = [System.Windows.Forms.MessageBox]::Show( "Dou you want to continue erasing all files?", "Please Confirm", "YesNoCancel", "Warning" )

 

And this is what the result of the previous code will look like:

Screenshot of PowerShell MessageBox simple demo       Screenshot of PowerShell MessageBox YesNoCancel demo

18. InputBox

  1. Add-Type -AssemblyName Microsoft.VisualBasic
  2. $name = [Microsoft.VisualBasic.Interaction]::InputBox( 'Please enter your name', 'Name', $Env:UserName )

 

And this is what the result of the previous code will look like:

Screenshot of PowerShell InputBox simple demo

19. Login dialog

  1. $cred = Get-Credential $UserName # UserName is optional
  2. $newUsername = $cred.GetNetworkCredential( ).UserName
  3. $password = $cred.GetNetworkCredential( ).Password

 

And this is what the result of the previous code will look like:

Screenshot of PowerShell Login Dialog

20. Select file dialog

  1. Add-Type -AssemblyName System.Windows.Forms
  2. $initialDirectory = [Environment]::GetFolderPath( 'MyDocuments' )
  3. $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
  4. $OpenFileDialog.InitialDirectory = $initialDirectory
  5. $OpenFileDialog.Filter = 'Batch files (*.bat;*.cmd)|*.bat;*.cmd'
  6. $OpenFileDialog.Multiselect = $false
  7. $response = $OpenFileDialog.ShowDialog( ) # $response will be OK or Cancel
  8. if ( $response -eq 'OK' ) { Write-Host 'Selected file:' $OpenFileDialog.FileName }

 

And this is what the result of the previous code will look like:

Screenshot of PowerShell Select File dialog

21. Browse for folder dialog

  1. $shell = New-Object -ComObject Shell.Application
  2. $selectedfolder = $shell.BrowseForFolder( 0, 'Select a folder', 16, $shell.NameSpace( 17 ).Self.Path ).Self.Path

 

And this is what the result of the previous code will look like:

Screenshot of PowerShell Browse For Folder dialog

22. Print dialog

  1. Add-Type -AssemblyName System.Windows.Forms
  2. $printdialog = New-Object System.Windows.Forms.PrintDialog
  3. $printdialog.AllowCurrentPage = $false
  4. $printdialog.AllowPrintToFile = $false
  5. $printdialog.AllowSelection = $false
  6. $printdialog.AllowSomePages = $false
  7. $printdialog.ShowNetwork = $false
  8. $response = $printdialog.ShowDialog( ) # $response will be OK or Cancel
  9. if ( $response -eq 'OK' ) { Write-Host 'Selected printer:' $printdialog.PrinterSettings.PrinterName }

 

And this is what the result of the previous code will look like:

Screenshot of PowerShell Print dialog

23. Select printer dialog

  1. Add-Type -AssemblyName System.Windows.Forms
  2. Add-Type -AssemblyName System.Drawing
  3.  
  4. $form = New-Object -TypeName System.Windows.Forms.Form
  5. $form.Text = 'Select a printer'
  6. $form.Size = '400, 200'
  7.  
  8. $list = @( ( Get-Printer ).Name )
  9. $Script:selectedvalue = ''
  10.  
  11. $dropdown = New-Object -TypeName System.Windows.Forms.ComboBox
  12. $dropdown.Items.AddRange( $list )
  13. $dropdown.SelectedIndex = 0
  14. $dropdown.Width = '200'
  15. $dropdown.Location = New-Object System.Drawing.Point( [int]( ( $form.Width - $dropdown.Width ) / 2 ), 25 )
  16. $form.Controls.Add( $dropdown )
  17.  
  18. $buttonOK_Click = {
  19. 	$Script:selectedvalue = $dropdown.Text
  20. 	$form.DialogResult = 'OK'
  21. 	$form.Close( )
  22. }
  23.  
  24. $buttonOK = New-Object System.Windows.Forms.Button
  25. $buttonOK.Text = 'OK'
  26. $buttonOK.Location = New-Object System.Drawing.Point( [int]( ( $form.Width / 2 ) - 5 - $buttonOK.Width ), 100 )
  27. $buttonOK.Add_Click( $buttonOK_Click )
  28. $form.Controls.Add( $buttonOK )
  29. $form.AcceptButton = $buttonOK # pressing Enter assumes OK
  30.  
  31. $buttonCancel_Click = {
  32. 	$form.DialogResult = 'Cancel'
  33. 	$form.Close( )
  34. }
  35.  
  36. $buttonCancel = New-Object System.Windows.Forms.Button
  37. $buttonCancel.Text = 'Cancel'
  38. $buttonCancel.Location = New-Object System.Drawing.Point( [int]( ( $form.Width / 2 ) + 5 ), 100 )
  39. $buttonCancel.Add_Click( $buttonCancel_Click )
  40. $form.Controls.Add( $buttonCancel )
  41. $form.CancelButton = $buttonCancel # pressing Esc assumes Cancel
  42.  
  43. $result = $form.ShowDialog( )
  44.  
  45. if ( $result -eq 'OK' ) {
  46. 	$Script:selectedvalue
  47. }

 

And this is what the result of the previous code will look like:

Screenshot of PowerShell Select Printer dialog

Screenshot of PowerShell Select Printer dialog

24. Find Network Printer dialog

  1. $shell = New-Object -ComObject Shell.Application
  2. $shell.FindPrinter( )

 

And this is what the result of the previous code will look like:

Screenshot of PowerShell Find Printer dialog

25. Open the Printers folder

  1. # See the ShellSpecialFolderConstants enumeration for details:
  2. # https://docs.microsoft.com/en-us/windows/win32/api/shldisp/ne-shldisp-shellspecialfolderconstants
  3. $shell = New-Object -ComObject Shell.Application
  4. $shell.Open( 4 )
  5.  
  6. # or:
  7.  
  8. # Source: "Shell folders: the best-kept Windows time saving secret" by Mike Williams
  9. # https://www.techradar.com/news/computing/pc/shell-folders-the-best-kept-windows-time-saving-secret-464668
  10. Start-Process -FilePath shell:PrintersFolder

 

26. Open the Network Neigborhood

  1. # See the ShellSpecialFolderConstants enumeration for details:
  2. # https://docs.microsoft.com/en-us/windows/win32/api/shldisp/ne-shldisp-shellspecialfolderconstants
  3. $shell = New-Object -ComObject Shell.Application
  4. $shell.Open( 18 )

 

Use this list of special folders constants to open other special folders using the Shell.Application COM object.
Instead of an integer special folder constant, you may also specify an "ordinary" folder path as string.

27. Open Network Places

  1. # Source: "Shell folders: the best-kept Windows time saving secret" by Mike Williams
  2. # https://www.techradar.com/news/computing/pc/shell-folders-the-best-kept-windows-time-saving-secret-464668
  3. Start-Process -FilePath shell:NetworkPlacesFolder
  4.  
  5. # or:
  6.  
  7. Start-Process -FilePath shell:::{F02C1A0D-BE21-4350-88B0-7367FC96EF3C}

 

28. Open the Add/Remove Programs dialog

  1. # Source: "Shell folders: the best-kept Windows time saving secret" by Mike Williams
  2. # https://www.techradar.com/news/computing/pc/shell-folders-the-best-kept-windows-time-saving-secret-464668
  3. Start-Process shell:ChangeRemoveProgramsFolder
  4.  
  5. # or:
  6.  
  7. Start-Process shell:::{26EE0668-A00A-44D7-9371-BEB064C98683}\0\::{7b81be6a-ce2b-4676-a29e-eb907a5126c5}

 

29. Find Computerter dialog

  1. $shell = New-Object -ComObject Shell.Application
  2. $shell.FindComputer( )

 

And this is what the result of the previous code will look like:

Screenshot of PowerShell Find Computer dialog

30. Font select dialog

  1. Add-Type -AssemblyName System.Windows.Forms
  2. $selectedfont = $null
  3. $fontdialog = New-Object System.Windows.Forms.FontDialog
  4. if ( $fontdialog.ShowDialog( ) -eq 'OK' ) {
  5. 	$selectedfont = $fontdialog.Font
  6. }
  7. $selectedfont

 

And this is what the result of the previous code will look like:

Screenshot of PowerShell Font Select dialog

31. Open the Fonts folder

  1. # Source: "Shell folders: the best-kept Windows time saving secret" by Mike Williams
  2. # https://www.techradar.com/news/computing/pc/shell-folders-the-best-kept-windows-time-saving-secret-464668
  3. Start-Process -FilePath shell:Fonts

 

32. Date picker dialog

  1. Add-Type -AssemblyName System.Windows.Forms
  2. Add-Type -AssemblyName System.Drawing
  3. $Script:selecteddate = ( Get-Date ).Date # default if canceled
  4.  
  5. $form = New-Object System.Windows.Forms.Form
  6. $form.Size = New-Object System.Drawing.Size( 360, 200 )
  7. $form.Text = 'Pick a date within 1 month'
  8.  
  9. $datepicker = New-Object System.Windows.Forms.DateTimePicker
  10. $datepicker.MinDate = ( Get-Date ) # no past dates allowed
  11. $datepicker.MaxDate = ( Get-Date ).AddMonths( 1 ) # allow dates within 1 month only
  12. $datepicker.Location = New-Object System.Drawing.Point( [int]( ( $form.Width - $datepicker.Width ) / 2 ), 40 )
  13. $form.Controls.Add( $datepicker )
  14.  
  15. $buttonOK_Click = {
  16. 	$Script:selecteddate = $datepicker.Value.Date
  17. 	$form.DialogResult = 'OK'
  18. 	$form.Close( )
  19. }
  20.  
  21. $buttonOK = New-Object System.Windows.Forms.Button
  22. $buttonOK.Text = 'OK'
  23. $buttonOK.Location = New-Object System.Drawing.Point( [int]( $form.Width / 2 ) - 5 - $buttonOK.Width, 100 )
  24. $buttonOK.Add_Click( $buttonOK_Click )
  25. $form.Controls.Add( $buttonOK )
  26. $form.AcceptButton = $buttonOK # pressing Enter assumes OK
  27.  
  28. $buttonCancel_Click = {
  29. 	$form.DialogResult = 'Cancel'
  30. 	$form.Close( )
  31. }
  32.  
  33. $buttonCancel = New-Object System.Windows.Forms.Button
  34. $buttonCancel.Text = 'Cancel'
  35. $buttonCancel.Location = New-Object System.Drawing.Point( [int]( $form.Width / 2 ) + 5, 100 )
  36. $buttonCancel.Add_Click( $buttonCancel_Click )
  37. $form.Controls.Add( $buttonCancel )
  38. $form.CancelButton = $buttonCancel # pressing Esc assumes Cancel
  39.  
  40. $result = $form.ShowDialog( )
  41. if ( $result -eq 'OK' ) {
  42. 	Write-Host ( "Selected date: {0}" -f $Script:selecteddate.ToString( 'yyyy-MM-dd' ) )
  43. }

 

And this is what the result of the previous code will look like:

Screenshot of Date Picker Dialog

Screenshot of Date Picker Dialog

33. Quick-and-dirty date picker alternative with Out-GridView

  1. $startdate = $( Get-Date ).Date        # or pick any other start date
  2. $enddate   = $startdate.AddMonths( 1 ) # or pick any other end date
  3. $title     = 'Select a date within a month from now' # adjust the title for the chosen date range
  4. # First convert dates to integers so we can define a range, next convert back to dates, next select
  5. # to show date only, then format the date, and finally show as list in GridView to select a value
  6. $selecteddate = $( $startdate.ToOADate( )..$enddate.ToOADate( ) `
  7.               | ForEach-Object { [DateTime]::FromOADate( $_ ) } `
  8. 			  | Select-Object Date `
  9. 			  | ForEach-Object { $_.Date.ToString( 'yyyy-MM-dd' ) } `
  10. 			  | Out-GridView -Title $title -PassThru )
  11. "Selected date: $selecteddate"

 

And this is what the result of the previous code will look like:

Screenshot of Date Picker Dialog in GridView

34. Color picker dialog

  1. Add-Type -AssemblyName System.Windows.Forms
  2. $colorDialog = New-Object System.Windows.Forms.ColorDialog
  3. $colorDialog.SolidColorOnly = $true
  4. if ( $colorDialog.ShowDialog( ) -eq 'OK' ) {
  5. 	# if the selected color doesn't have a name, the hexadecimal RGB value will be returned
  6. 	Write-Host ( "Selected color: {0}" -f $colorDialog.Color.Name )
  7. }

 

And this is what the result of the previous code will look like:

Screenshot of Color Picker Dialog

35. Embed base-64 encoded icon

  1. Add-Type -AssemblyName System.Windows.Forms
  2. Add-Type -AssemblyName System.Drawing
  3. # Base64 encoded icon
  4. $b64convicon  = "AAABAAEAEBAQAAEABAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAAAAAAAAA"
  5. $b64convicon += "AAAAAAAAAAAAAAAAAAAEAgQAhIKEAPz+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
  6. $b64convicon += "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
  7. $b64convicon += "AAAAAAAAAAAAAAAAAAAAEiEAAAICAAEgAgEAAgEgAgAAAgARACECAAAAACAAAgIA"
  8. $b64convicon += "AAEAIAACAgAAAgEQACEBIAIAAgABIAASIQACAAIAAAAAAAAAAAAAAAAAAAAAAAAA"
  9. $b64convicon += "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
  10. $b64convicon += "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
  11. $form = New-Object System.Windows.Forms.Form
  12. # Use Base64 encoded icon in code, by Kenny Baldwin
  13. # https://foxdeploy.com/2013/10/23/creating-a-gui-natively-for-your-powershell-tools-using-net-methods/#comments
  14. $form.Icon = ( [System.Drawing.Icon]( New-Object System.Drawing.Icon( ( New-Object System.IO.MemoryStream( ( $$ = [System.Convert]::FromBase64String( $b64convicon ) ), 0, $$.Length ) ) ) ) )
  15. $form.ShowDialog( )

 

And this is what the result of the previous code will look like (note the C: icon):

Screenshot of PowerShell embedded icon

36. Show an icon in the System Tray (a.k.a. Notification Area)

  1. # System Tray ToolTip Balloon by Don Jones
  2. # http://blog.sapien.com/current/2007/4/27/creating-a-balloon-tip-notification-in-powershell.html
  3. Add-Type -AssemblyName System.Windows.Forms
  4. Add-Type -AssemblyName System.Drawing
  5. # Base64 encoded icon
  6. $b64convicon  = 'AAABAAEAEBAQAAEABAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAAAAAAAAA'
  7. $b64convicon += 'AAAAAAAAAAAAAAAAAAAEAgQAhIKEAPz+/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
  8. $b64convicon += 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
  9. $b64convicon += 'AAAAAAAAAAAAAAAAAAAAEiEAAAICAAEgAgEAAgEgAgAAAgARACECAAAAACAAAgIA'
  10. $b64convicon += 'AAEAIAACAgAAAgEQACEBIAIAAgABIAASIQACAAIAAAAAAAAAAAAAAAAAAAAAAAAA'
  11. $b64convicon += 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
  12. $b64convicon += 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
  13. # Use Base64 encoded icon in code, by Kenny Baldwin
  14. # https://foxdeploy.com/2013/10/23/creating-a-gui-natively-for-your-powershell-tools-using-net-methods/#comments
  15. $icon = [System.Drawing.Icon]( New-Object System.Drawing.Icon( ( New-Object System.IO.MemoryStream( ( $$ = [System.Convert]::FromBase64String( $b64convicon ) ), 0, $$.Length ) ) ) )
  16. $notify = new-object system.windows.forms.notifyicon
  17. $notify.icon = $icon
  18. $notify.visible = $true
  19. # show the balloon for 10 seconds (will not show in Windows 10)
  20. $notify.showballoontip( 10, "Reminder", "It's scripting time", [system.windows.forms.tooltipicon]::Info )
  21. # Uncomment the next command line to remove the icon, or type it manually, or
  22. # close the balloon and hover the mouse pointer over the system tray icon.
  23. # $notify.Visible = $false

 

And this is what the result of the previous code will look like (we just inserted the C: icon):

 Screenshot of PowerShell generated System Tray icon

37. Open a Run dialog (same as Start Menu > Run)

  1. $shell = New-Object -ComObject Shell.Application
  2. $shell.FileRun( )

 

And this is what the result of the previous code will look like:

Screenshot of Run dialog started by PowerShell

38. Open a Shutdown Windows dialog

  1. $shell = New-Object -ComObject Shell.Application
  2. $shell.ShutdownWindows( )
  3.  
  4. # or as a one-liner:
  5.  
  6. ( New-Object -ComObject Shell.Application ).ShutdownWindows( )

 

And this is what the result of the previous code will look like:

Screenshot of Shutdown Windows Dialog


page last modified: 2024-03-11; loaded in 0.7771 seconds