======Microsoft - Scripting - PowerShell - Notes====== =====Determine PowerShell version===== $PSVersionTable.PSVersion [[http://stackoverflow.com/questions/1825585/determine-installed-powershell-version|Stack Overflow - Determine installed PowerShell version]] \\ =====Arrays===== [[http://thephuck.com/scripts/easy-way-to-check-if-your-powershell-variable-is-an-array-or-not/|ThepHuck - Easy way to check if your PowerShell variable is an array or not]] \\ ====Array has fixed size==== Using the .Add or .RemoveRange methods on an array object in PowerShell will not work. The Array.IsFixedSize property is always true for all arrays. Source: [[https://msdn.microsoft.com/en-us/library/system.array.isfixedsize.aspx|Microsoft MSDN - Array.IsFixedSize Property]] via [[https://social.msdn.microsoft.com/Forums/en-US/c13ea9bd-dac4-44be-99f7-272a8eb0c55d/using-the-add-method-on-an-array?forum=winserverpowershell|Microsoft MSDN forum - Using the .Add method on an array]] \\ =====Printer===== Get the Name, port, location, comment, drivername and printservername of every printer on this system and export this to a CSV: Get-WmiObject Win32_Printer | Select-Object Name,PortName,Location,Comment,DriverName,SystemName | Export-CSV test.csv =====Bug in Powershell v3 on regional settings===== On Windows Server 2012 RTM with a language setting other than en-US, several fields in PowerShell output are empty. An example are the LevelDisplayName and Message fields of the Get-WinEvent cmdlet. To work around this use the following function in your script: function Using-Culture ( [System.Globalization.CultureInfo] $culture = (throw "USAGE: Using-Culture -Culture culture -Script {...}"), [ScriptBlock] $script = (throw "USAGE: Using-Culture -Culture culture -Script {...}")) { $OldCulture = [Threading.Thread]::CurrentThread.CurrentCulture $OldUICulture = [Threading.Thread]::CurrentThread.CurrentUICulture try { [Threading.Thread]::CurrentThread.CurrentCulture = $culture [Threading.Thread]::CurrentThread.CurrentUICulture = $culture Invoke-Command $script } finally { [Threading.Thread]::CurrentThread.CurrentCulture = $OldCulture [Threading.Thread]::CurrentThread.CurrentUICulture = $OldUICulture } } Source: Keith Hill on [[http://stackoverflow.com/questions/4105224/how-to-set-culture-in-powershell|stackoverflow - How to set culture in PowerShell?]] \\ And execute Get-WinEvent like so: Using-Culture -Culture en-US -Script {Get-WinEvent -logname System -maxevents 10 -computername Server01} Sources: \\ [[http://vniklas.djungeln.se/2013/01/09/bug-in-get-winevent-on-windows-2012/|vNiklas Virtualization blog - Bug in Get-WinEvent on Windows 2012?]] \\ [[http://vniklas.djungeln.se/2013/01/09/bug-in-powershell-v3-on-regional-settings-in-windows-2012/|vNiklas Virtualization blog - Bug in Powershell v3 on regional settings in Windows 2012]] \\ [[http://stackoverflow.com/questions/10534982/powershell-get-winevent-has-no-messsage-data|stackoverflow - powershell: get-winevent has no messsage data?]] \\ [[https://connect.microsoft.com/PowerShell/feedback/details/716533/get-winevent-does-not-return-the-content-of-the-event-message-in-v3-ctp2|Microsoft Connect - Get-WinEvent does not return the content of the Event Message in V3 CTP2]] \\ =====If today is the fourth Saturday of the month===== Quick and dirty way to check if today is the fourth Saturday of this month: $dateCurrentDay = Get-Date if ( $dateCurrentDay.DayOfWeek -eq "Saturday" ) { # If this Saturday is the fourth Saturday of the month... if ( ($dateCurrentDay.Day / 7 -gt 3) -and ($dateCurrentDay.Day / 7 -le 4) ) { "Do something." } } =====Write to text file===== Append a line of text to a file: $strLogFile = "C:\TEMP\script.log" "Removing current files:" | Out-File -FilePath "$strLogFile" -Append The same can be done with command output: Get-Item "C:\Windows\Temp\*.tmp" | Out-File -FilePath "$strLogFile" -Append =====Take arguments===== To use a parameter $strJobName = [string]$args[0] Source: [[http://stackoverflow.com/questions/6359618/pass-parameter-from-batch-file-to-the-powershell-script|Stackoverflow - Pass parameter from batch file to the powershell script]] \\ =====Add parameters===== Add to the beginning of the script: [CmdletBinding()] param( [Parameter(Mandatory)] [string]$TaskName, [Parameter()] [string]$Property ) Types can be (among others): * string * switch * int * boolean Source: * [[https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_parameter_sets|Microsoft Docs - about_Parameter_Sets]] * [[https://ss64.com/ps/syntax-args.html|SS64.com - PowerShell Parameters]] * [[https://ss64.com/ps/syntax-function-advanced.html|SS64.com - Write an Advanced Function]] =====Rename computer===== Rename the local computer and restart: Rename-Computer -NewName newcomputername -Restart =====Restart computer===== Restart the local computer: Restart-Computer =====Promote first AD DS Domain Controller===== Import-Module ADDSDeployment Install-ADDSForest ` -CreateDnsDelegation:$false ` -DatabasePath "C:\Windows\NTDS" ` -DomainMode "Win2008" ` -DomainName "testing.local" ` -DomainNetbiosName "TESTING" ` -ForestMode "Win2008" ` -InstallDns:$true ` -LogPath "C:\Windows\NTDS" ` -NoRebootOnCompletion:$false ` -SysvolPath "C:\Windows\SYSVOL" ` -Force:$true =====Create an object and add it to another===== # Create the objReport variable $objReport = @() foreach ( $strSomething in $arrSomething ) { # Create the objTemp variable $objTemp = "" | Select-Object "Name","Missing Group","Group Permissions" # Fill the objTemp variable $objTemp."Name" = $strName $objTemp."Missing Group" = $strGroup $objTemp."Group Permissions" = $strPerms # Add the filled objTemp to objReport $objReport += $objTemp # Cleanup $objTemp = $null } # Display the report $objReport # Cleanup $objReport = $null =====Redirect StdError and StdOutput to the same log file===== To redirect both standard and error output from a command line tool to a text file from PowerShell, either use: command.exe 2>&1 | Out-File C:\Logs\Logfile.txt Or: command.exe 2>&1 > C:\Logs\Logfile.txt Source:[[http://stackoverflow.com/questions/8925323/redirection-of-standard-and-error-output-appending-to-the-same-log-file|Stack Overflow - Redirection of standard and error output appending to the same log-file]] \\ =====Check if the PowerShell prompt is elevated===== # Check if the PowerShell prompt was started with elevation: # Source: http://stackoverflow.com/questions/7985755/how-to-detect-if-cmd-is-running-as-administrator-has-elevated-privileges $objPrincipal = new-object System.Security.Principal.WindowsPrincipal([System.Security.Principal.WindowsIdentity]::GetCurrent()) if ($objPrincipal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)) { Write-Host "Please start this script in an elevated PowerShell prompt." -ForeGroundColor Red Exit } Source: [[http://stackoverflow.com/questions/7985755/how-to-detect-if-cmd-is-running-as-administrator-|Stack Overflow - How to detect if CMD is running as Administrator/has elevated privileges?]] \\ =====Get UNIX time===== Get-Date -UFormat %s Get UNIX time from 30 days ago: Get-Date -UFormat %s (Get-Date).AddDays(-30) Source: [[https://devblogs.microsoft.com/scripting/powertip-use-unix-date-formatting-in-powershell/|Microsoft Scripting - PowerTip: Use UNIX Date Formatting in PowerShell]] =====Hexadecimal to Decimal and Decimal to Hexadecimal====== Hex to dec: [uint32]0x41303 Source: [[https://stackoverflow.com/questions/38567479/hex-to-decimal-conversion-powershell-5#38567654|stack overflow - Hex to Decimal Conversion - PowerShell 5]] Dec to hex: "0x{0:X}" -f 267011 > Source: [[https://stackoverflow.com/questions/54512136/how-to-convert-decimal-to-hexadecimal-variable#57999927|stack overflow - How to convert decimal to hexadecimal variable?]] =====Convert UTC DateTime to another timezone===== $datetime = Get-Date $datetime.ToUniversalTime() [TimeZoneInfo]::ConvertTimeBySystemTimeZoneId($datetime, 'W. Europe Standard Time') To get a list of timezones: [TimeZoneInfo]::GetSystemTimeZones() | Select-Object Id, DisplayName Source:[[https://stackoverflow.com/questions/58802973/how-to-convert-powershell-utc-datetime-object-to-est|stack overflow - How to convert powershell UTC datetime object to EST]] =====Print error message===== Print most recent error message: $Error[0].Exception