ClipboardTools.psm1
<#
.Synopsis This function gets clipboard data and sets it back to clipboard removing any metadata .DESCRIPTION This function gets clipboard data and sets it back to clipboard. This trick should remove metadata from clipboard data. For example from http smartlinks it will paste full url instead of url smartlink (url name and url) Author: Petri.Paavola@yodamiitti.fi Senior Modern Management Principal Microsoft MVP - Windows and Intune 2024-09-14 https://github.com/petripaavola/ClipboardTools .PARAMETER PassThru PassThru parameter will also output clipboard data to PowerShell pipeline. Usually this is used with saving results to variable. For example $FromClipboard = ClipboardTools-CopyPaste -PassThru .EXAMPLE ClipboardTools-CopyPaste .EXAMPLE $FromClipboard = ClipboardTools-CopyPaste -PassThru .INPUTS Reads clipboard data .OUTPUTS Outputs data to clipboard With parameter -PassThru output is sent to PowerShell pipeline .NOTES None .LINK https://github.com/petripaavola/ClipboardTools #> Function ClipboardTools-CopyPaste { [CmdletBinding()] Param ( [Parameter(Mandatory=$false)] [Switch]$PassThru ) if(Get-Clipboard) { Get-Clipboard | Set-Clipboard if(-not $PassThru) { Write-Host "Clipboard ready to paste:" -Foregroundcolor Green Get-Clipboard } } else { Write-Host "Clipboard was empty" -ForeGroundColor Yellow return $null } if($PassThru) { return Get-Clipboard } } <# .Synopsis This function extracs smart html link's title and url and pastes them back to clipboard .DESCRIPTION This function extracs smart html link's title and url and pastes them back to clipboard in 2 separate lines This is good trick to paste smart html link title and url separately to document. Author: Petri.Paavola@yodamiitti.fi Senior Modern Management Principal Microsoft MVP - Windows and Intune 2023-09-24 https://github.com/petripaavola/ClipboardTools .EXAMPLE ClipboardTools-CopyPasteUrl .INPUTS Reads clipboard data .OUTPUTS Outputs extracted smart html link's title and url to clipboard .NOTES None .LINK https://github.com/petripaavola/ClipboardTools #> Function ClipboardTools-CopyPasteUrl { # Example string in Array # <!--StartFragment--><a href="https://learn.microsoft.com/en-us/PowerShell/module/psreadline/about/about_psreadline?source=recommendations&view=PowerShell-7.3">about PSReadLine - PowerShell | Microsoft Learn</a><!--EndFragment--> $Clipboard = Get-Clipboard -TextFormatType Html # Get line containing html fragment using normal Array filtering $HtmlFragment = $Clipboard | Where-Object { $_ -like "<!--StartFragment-->*<!--EndFragment-->" } if($HtmlFragment) { # Use -Match (regex) to extract Title and Url # Test regex in https://regex101.com # Using String: # <!--StartFragment--><a href="https://learn.microsoft.com/en-us/PowerShell/module/psreadline/about/about_psreadline?source=recommendations&view=PowerShell-7.3">about PSReadLine - PowerShell | Microsoft Learn</a><!--EndFragment--> $Matches = $null $regex = '^<!--StartFragment--><a href="(.*)">(.*)<\/a><!--EndFragment-->$' if($HtmlFragment -Match $regex) { $Topic = $Matches[2] Set-Clipboard $Topic $url = $Matches[1] Set-Clipboard $url -Append Write-Host "Clipboard ready to paste:" -Foregroundcolor Green Get-Clipboard } else { Write-Host "Warning: did not find url type clipboard information" -Foregroundcolor Yellow } } else { Write-Host "Did not find url type clipboard information" -Foregroundcolor Yellow } } <# .Synopsis This function converts PowerShell objects to a tab-delimited CSV format and copies the data to the clipboard for easy pasting into Excel. .DESCRIPTION This function processes PowerShell objects from the pipeline and converts them to a tab-delimited CSV format. The resulting CSV is copied to the clipboard, allowing users to paste the data directly into Excel. This simplifies data transfer from PowerShell to Excel, especially for reporting and analysis purposes. Author: Petri.Paavola@yodamiitti.fi Senior Modern Management Principal Microsoft MVP - Windows and Intune 2024-09-14 https://github.com/petripaavola/ClipboardTools .PARAMETER PowershellObjects Specifies the objects to be converted to tab-delimited CSV format. These objects can be passed via the pipeline. .EXAMPLE Get-Service | ClipboardTools-PasteObjectToExcel .EXAMPLE $myData | ClipboardTools-PasteObjectToExcel .INPUTS Accepts objects from the pipeline. The objects are converted to a tab-delimited CSV format. .OUTPUTS Tab-delimited CSV data copied to the clipboard, which can be pasted into Excel. .NOTES This function is designed for quick data export to Excel by copying objects as tab-delimited CSV to the clipboard. .LINK https://github.com/petripaavola/ClipboardTools #> function ClipboardTools-PasteObjectToExcel { Param( [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)] $PowershellObjects ) Begin { $arrayOfObjects = @() } Process { # Collect each object passed from the pipeline $arrayOfObjects += $PowershellObjects } End { Write-Host "Export data to Clipboard so you can paste it to Excel`n" # Convert the array of objects to CSV and copy to clipboard Write-Host "Convert $($arrayOfObjects.Count) objects to tab limited CSV format" $CSVToClipboard = $arrayOfObjects | ConvertTo-Csv -Delimiter "`t" -NoTypeInformation $Success = $? if($Success) { Write-Host "Success`n" -ForegroundColor Green Write-Host "Copy data to Clipboard" $CSVToClipboard | Set-Clipboard $Success = $? if($Success) { Write-Host "Success. You can now paste data to Excel`n" -ForegroundColor Green } else { Write-Host "Success: Failed`n" -ForegroundColor Red } } else { Write-Host "Converting objects data to csv failed!`n" -ForegroundColor Yellow } } } <# .Synopsis This function creates new GUID and copies it to clipboard .DESCRIPTION This function creates new GUID and copies it to clipboard. You can then paste it to anywhere. Author: Petri.Paavola@yodamiitti.fi Senior Modern Management Principal Microsoft MVP - Windows and Intune 2023-09-24 https://github.com/petripaavola/ClipboardTools .EXAMPLE ClipboardTools-NewGuidToClipboard .INPUTS Reads clipboard data .OUTPUTS Outputs new GUID to clipboard .NOTES None .LINK https://github.com/petripaavola/ClipboardTools #> Function ClipboardTools-NewGuidToClipboard { $Guid = (New-Guid).Guid $Guid | Set-Clipboard $Success = $? if($Success) { Write-Host "$Guid copied to clipboard" -ForegroundColor Green } } <# .Synopsis This function reads JSON data from clipboard and sets uncompressed JSON back to clipboard .DESCRIPTION This function reads JSON data from clipboard and sets uncompressed JSON back to clipboard This is good trick to extract compressed JSON and also do JSON syntax validation. Conversion checks that JSON syntax is valid at the same time. With -PassThru parameter converted JSON data is sent to PowerShell pipeline and can be saved to PowerShell variable. Author: Petri.Paavola@yodamiitti.fi Senior Modern Management Principal Microsoft MVP - Windows and Intune 2023-09-24 https://github.com/petripaavola/ClipboardTools .PARAMETER PassThru PassThru parameter will also output converted JSON data to PowerShell pipeline. Usually this is used with saving results to variable. For example $FromJson = ClipboardTools-JsonUncompress -PassThru .PARAMETER RemovePowerShellEscapes Remove PowerShell escape character ` from JSON before converting data We can get escaped JSON for example from Edge Debugger This is for special cases .PARAMETER RemoveDoubleJsonEscapes Replace double JSON escape \\\\ to \\ from JSON data before converting JSON This is super rare case but sometimes when original JSON data has nested JSON data in properties they get double escaped which causes problems later. .EXAMPLE ClipboardTools-JsonUncompress .EXAMPLE $FromJson = ClipboardTools-JsonUncompress -PassThru .EXAMPLE ClipboardTools-JsonUncompress -RemovePowerShellEscapes .EXAMPLE ClipboardTools-JsonUncompress -RemoveDoubleJsonEscapes .INPUTS Reads clipboard JSON data .OUTPUTS Outputs syntax checked and uncompressed JSON to clipboard .NOTES None .LINK https://github.com/petripaavola/ClipboardTools #> Function ClipboardTools-JsonUncompress { Param ( [Parameter(Mandatory=$false)] [Switch] $PassThru, [Parameter(Mandatory=$false)] [Switch] $RemovePowerShellEscapes, [Parameter(Mandatory=$false)] [Switch] $RemoveDoubleJsonEscapes ) $Clipboard = Get-Clipboard if($Clipboard) { # Remove PowerShell ` escape characters if($RemoveEscapes) { $Clipboard = $Clipboard.Replace('`','') } # Remove Json double escapes \\\\ -> \\ if($RemoveDoubleJsonEscapes) { $Clipboard = $Clipboard -replace('\\\\', '\\') } # Convert Clipboard Json data to variable Try { $json = $Clipboard | ConvertFrom-Json $Success = $? if($Success) { $json | ConvertTo-Json -Depth 10 | Set-Clipboard if($PassThru) { return $json } else { Write-Host "Paste uncompressed JSON to text editor with Ctrl-v" -Foregroundcolor Green } } else { Write-Host "Warning: Could not convert JSON data from clipboard" -ForegroundColor Yellow } } Catch { Write-Host "Warning: Clipboard data is not valid JSON" -ForegroundColor Yellow return $null } } else { Write-Host "Clipboard was empty" -ForeGroundColor Yellow } } <# .Synopsis This function reads JSON data from clipboard and puts compressed JSON back to clipboard .DESCRIPTION This function reads JSON data from clipboard and puts compressed JSON back to clipboard Conversion also checks that JSON syntax is valid. With -PassThru parameter compressed JSON data is sent to PowerShell pipeline and can be saved to PowerShell variable. Author: Petri.Paavola@yodamiitti.fi Senior Modern Management Principal Microsoft MVP - Windows and Intune 2023-09-24 https://github.com/petripaavola/ClipboardTools .PARAMETER PassThru PassThru parameter will also output converted JSON data to PowerShell pipeline. Usually this is used with saving results to variable. For example $CompressedJson = ClipboardTools-JsonCompress -PassThru .EXAMPLE ClipboardTools-JsonCompress .EXAMPLE $FromJson = ClipboardTools-JsonCompress -PassThru .INPUTS Reads clipboard JSON data .OUTPUTS Outputs syntax checked and compressed JSON to clipboard .NOTES None .LINK https://github.com/petripaavola/ClipboardTools #> Function ClipboardTools-JsonCompress { Param ( [Parameter(Mandatory=$false)] [Switch] $PassThru ) $Clipboard = Get-Clipboard if($Clipboard) { # Convert Compressed Clipboard Json data to variable Try { $json = $Clipboard | ConvertFrom-Json $Success = $? if($Success) { $json | ConvertTo-Json -Depth 10 -Compress | Set-Clipboard if($PassThru) { return $json } else { Write-Host "Paste compressed JSON to text editor with Ctrl-v" -Foregroundcolor Green } } else { Write-Host "Warning: Could not convert JSON data from clipboard" -ForegroundColor Yellow } } Catch { Write-Host "Warning: Clipboard data is not valid JSON" -ForegroundColor Yellow return $null } } else { Write-Host "Clipboard was empty" -ForeGroundColor Yellow } } <# .Synopsis This function reads image from clipboard and saves image to image file .DESCRIPTION This function reads image from clipboard and saves image to image file You can specify filename and folder with parameters -FileName and -FilePath By default file is saved to current directory and filename is {timestamp}-ImageCapture Example Filename: 20230922-ImageCapture.png Timestamp is always added before FileName. With parameter -OpenFileAfterSave file is opened to default image viewer application Author: Petri.Paavola@yodamiitti.fi Senior Modern Management Principal Microsoft MVP - Windows and Intune 2023-09-24 https://github.com/petripaavola/ClipboardTools .PARAMETER FileName FileName for saved image .PARAMETER FilePath FilePath for saved image .PARAMETER OpenImageAfterSave Opens saved image in default image application .EXAMPLE ClipboardTools-SaveImageToFile .EXAMPLE ClipboardTools-SaveImageToFile -Name 'ImageFileName' .EXAMPLE ClipboardTools-SaveImageToFile -Name 'ImageFileName' -FilePath D:\ScreenCaptures .EXAMPLE ClipboardTools-SaveImageToFile -OpenFileAfterSave .INPUTS Reads clipboard picture data .OUTPUTS Outputs image to file .NOTES None .LINK https://github.com/petripaavola/ClipboardTools #> Function ClipboardTools-SaveImageToFile { Param( [Parameter(Mandatory=$false)] $FileName = 'ImageCapture', [Parameter(Mandatory=$false)] $FilePath, [Parameter(Mandatory=$false)] [switch]$OpenFileAfterSave ) # Get image from clipboard $ImageFromClipboard = Get-Clipboard -Format Image if($ImageFromClipboard) { # Set image path, timestamp and filename to saved image file $timestamp = Get-Date -Format yyyyMMdd-HHmmss # Set current path for FilePath if parameter was not specified if(-not $FilePath) { $FilePath = $pwd.Path } # Check if destination folder exists if(-not (Test-Path $FilePath)) { Write-Host "Warning: destination directory $FilePath does not exist!" -ForegroundColor Yellow Write-Host "Defaulting to current folder $($pwd.Path)" $FilePath = $pwd.Path } $FileSavePath = "$($FilePath)\$($timestamp)-$($FileName).png" $ImageFromClipboard.Save($FileSavePath) $Success = $? if($Success) { Write-Host "Successfully saved file: $FileSavePath" -ForegroundColor Green if($OpenFileAfterSave) { Write-Host "Opening image to default image application`n" # Sleep 1 seconds to make sure image file is saved to folder # For example saving to slow USB drive may take some time to complete Start-Sleep -Seconds 1 if(Test-Path $FileSavePath) { # Open image to default image application Invoke-Item $FileSavePath } else { Write-Host "Warning: File save was not completed before opening image" -ForeGroundColor Yellow Write-Host "Skipping image opening...`n" } } } else { Write-Host "Failed to save file: $FileSavePath`n" -ForegroundColor Red } } else { Write-Host "Did not detect image from clipboard`n" -ForeGroundColor Yellow } } <# .Synopsis This function reads text from clipboard and saves text to text file .DESCRIPTION This function reads text from clipboard and saves text to text file You can specify filename and folder with parameters -FileName and -FilePath Default FileName is textfile.txt and default FilePath is current working directory With parameter -Append you can add text data to (new or) existing files With parameter -Force you can overwrite existing file With parameter -OpenFileAfterSave file is opened to default text editor Author: Petri.Paavola@yodamiitti.fi Senior Modern Management Principal Microsoft MVP - Windows and Intune 2023-09-24 https://github.com/petripaavola/ClipboardTools .PARAMETER FileName FileName for saved text file .PARAMETER FilePath FilePath for saved text file .PARAMETER Append Append text to existing file or create new text file .PARAMETER Force Overwrite existing file .PARAMETER OpenFileAfterSave Opens saved text file in default text editor .EXAMPLE ClipboardTools-SaveTextToFile .EXAMPLE ClipboardTools-SaveTextToFile -Name 'TextFile.txt' .EXAMPLE ClipboardTools-SaveTextToFile -Name 'TextFile.txt' -FilePath D:\temp .EXAMPLE ClipboardTools-SaveTextToFile -OpenFileAfterSave .EXAMPLE ClipboardTools-SaveTextToFile -Name 'TextFile.txt' -FilePath D:\temp -Append .EXAMPLE ClipboardTools-SaveTextToFile -Name 'TextFile.txt' -FilePath D:\temp -Force .INPUTS Reads clipboard text data .OUTPUTS Outputs clipboard text to file .NOTES None .LINK https://github.com/petripaavola/ClipboardTools #> Function ClipboardTools-SaveTextToFile { Param( [Parameter(Mandatory=$false)] $FileName = 'textfile.txt', [Parameter(Mandatory=$false)] $FilePath, [Parameter(Mandatory=$false)] [Switch]$Append, [Parameter(Mandatory=$false)] [Switch]$Force, [Parameter(Mandatory=$false)] [switch]$OpenFileAfterSave ) # Get Clipboard text $TextFromClipboard = Get-Clipboard -Format Text if($TextFromClipboard) { if(-not $FilePath) { $FilePath = $pwd.Path } $FileSavePath = "$FilePath\$FileName" if(((Test-Path $FileSavePath) -and (-not $Force)) -and ((Test-Path $FileSavePath) -and (-not $Append))){ Write-Host "Warning: Destination file already exists and -Force or -Append parameter NOT specified." -ForeGroundColor Yellow Write-Host "Will not overwrite file $filePath`n" } else { if($Append) { # Append clipboard text to possible existing file $TextFromClipboard | Add-Content -Path $FileSavePath $Success = $? if($Success) { Write-Host "Successfully appended text to file: $FileSavePath`n" -ForegroundColor Green } else { Write-Host "Failed to append text to file: $FileSavePath`n" -ForegroundColor Red } } elseif ($Force -and (-not $Append)) { # Overwrite possible existing files $TextFromClipboard | Set-Content -Path $FileSavePath -Force $Success = $? if($Success) { Write-Host "Successfully saved file: $FileSavePath`n" -ForegroundColor Green } else { Write-Host "Failed to save file: $FileSavePath`n" -ForegroundColor Red } } else { $TextFromClipboard | Set-Content -Path $FileSavePath $Success = $? if($Success) { Write-Host "Successfully saved file: $FileSavePath`n" -ForegroundColor Green } else { Write-Host "Failed to save file: $FileSavePath`n" -ForegroundColor Red } } Start-Sleep -Seconds 1 Write-Host "Opening text file to default text editor`n" # Sleep 1 seconds to make sure text file is saved to folder # For example saving to slow USB drive may take some time to complete if($OpenFileAfterSave) { if(Test-Path $FileSavePath) { # Open text file to default text editor Invoke-Item $FileSavePath } else { Write-Host "Warning: File save was not completed before opening" -ForeGroundColor Yellow Write-Host "Skipping text file opening...`n" } } } } else { Write-Host "Did not detect text from clipboard`n" -ForeGroundColor Yellow } } <# .Synopsis This function sorts text in clipboard either ascending (default) or descending order .DESCRIPTION This function sorts text in clipboard either ascending (default) or descending order With parameter -Descending you can set descending sort Author: Petri.Paavola@yodamiitti.fi Senior Modern Management Principal Microsoft MVP - Windows and Intune 2023-09-24 https://github.com/petripaavola/ClipboardTools .PARAMETER Descending Sort clipboard text descending .EXAMPLE ClipboardTools-Sort .EXAMPLE ClipboardTools-Sort -Descending .INPUTS Reads clipboard text data .OUTPUTS Outputs sorted clipboard text back to clipboard .NOTES None .LINK https://github.com/petripaavola/ClipboardTools #> Function ClipboardTools-Sort { Param( [Parameter(Mandatory=$false)] [Switch]$Descending = $false ) if(Get-Clipboard -Format Text) { if(-not $Descending) { Get-Clipboard -Format Text| Sort-Object | Set-Clipboard $Success = $? } else { Get-Clipboard -Format Text| Sort-Object -Descending | Set-Clipboard $Success = $? } if($Success) { if($Descending) { Write-Host "Clipboard text is now sorted in descending order`n" -ForegroundColor Green } else { Write-Host "Clipboard text is now sorted`n" -ForegroundColor Green } } else { Write-Host "Failed to sort Clipboard text`n" -ForegroundColor Red } } else { Write-Host "Clipboard did not contain any text`n" -ForeGroundColor Yellow } } <# .Synopsis This function checks if clipboard text has valid JSON syntax .DESCRIPTION This function checks if clipboard text has valid JSON syntax Author: Petri.Paavola@yodamiitti.fi Senior Modern Management Principal Microsoft MVP - Windows and Intune 2023-09-24 https://github.com/petripaavola/ClipboardTools .EXAMPLE ClipboardTools-ValidateJson .INPUTS Reads clipboard text .OUTPUTS None .NOTES None .LINK https://github.com/petripaavola/ClipboardTools #> Function ClipboardTools-ValidateJson { # Read Clipboard text $ClipboardText = Get-Clipboard -Format Text if($ClipboardText) { try { $json = $ClipboardText | ConvertFrom-Json $Success = $? if($Success) { Write-Host "Clipboard text has valid JSON syntax" -ForegroundColor Green } else { Write-Host "Clipboard text is NOT valid JSON syntax" -ForegroundColor Red } } catch { Write-Host "Clipboard text is NOT valid JSON syntax" -ForegroundColor Red } } else { Write-Host "Clipboard did not contain any text`n" -ForeGroundColor Yellow } } <# .Synopsis This function checks if XML file in clipboard has valid xml syntax .DESCRIPTION This function checks if XML file in clipboard has valid xml syntax With parameter -PassThru converted XML is sent to PowerShell pipeline and can be saved to PowerShell variable. Author: Petri.Paavola@yodamiitti.fi Senior Modern Management Principal Microsoft MVP - Windows and Intune 2023-09-24 https://github.com/petripaavola/ClipboardTools .PARAMETER PassThru PassThru parameter outputs converted XML text to PowerShell pipeline. Usually this is used with saving results to variable. .EXAMPLE ClipboardTools-ValidateXml .EXAMPLE $xml = ClipboardTools-ValidateXml -PassThru .INPUTS Reads clipboard data .OUTPUTS With parameter -PassThru converted XML is sent to PowerShell pipeline. .NOTES None .LINK https://github.com/petripaavola/ClipboardTools #> Function ClipboardTools-ValidateXml { Param( [Parameter(Mandatory=$false)] [Switch]$PassThru ) # Read Clipboard text $ClipboardText = Get-Clipboard -Format Text if($ClipboardText) { try { [xml]$xml = $ClipboardText $Success = $? if($Success) { Write-Host "Clipboard text has valid XML syntax" -ForegroundColor Green if($PassThru) { return $xml } } else { Write-Host "Clipboard text is NOT valid XML syntax" -ForegroundColor Red } } catch { Write-Host "Clipboard text is NOT valid XML syntax`n" -ForegroundColor Red Write-Host "$($_.Exception.Message)" -ForegroundColor Red } } else { Write-Host "Clipboard did not contain any text`n" -ForeGroundColor Yellow } } <# .Synopsis This function checks if PowerShell script copied to clipboard has valid PowerShell syntax .DESCRIPTION This function checks if PowerShell script copied to clipboard has valid PowerShell syntax This is done by using command: Get-Command -Syntax temporary_scriptfile.ps1 Text/PowerShell script from clipboard is saved to temporary file in TEMP directory PowerShell Syntax check is done to this temporary .ps1 file Temporary file is deleted after syntax check. This will NOT run the script. Author: Petri.Paavola@yodamiitti.fi Senior Modern Management Principal Microsoft MVP - Windows and Intune 2023-09-24 https://github.com/petripaavola/ClipboardTools .EXAMPLE ClipboardTools-ValidatePowerShellSyntax .INPUTS Reads PowerShell script from clipboard .OUTPUTS None But script will create temporary PowerShell script file to $env:temp which is deleted after syntax check .NOTES None .LINK https://github.com/petripaavola/ClipboardTools #> Function ClipboardTools-ValidatePowerShellSyntax { # Copy Clipboard text $PowerShellScriptFromClipboard = Get-Clipboard -Format Text if($PowerShellScriptFromClipboard) { # Copy file to temp directory and run it from there $PowerShellScriptPath = "$env:Temp\TestPowerShellScriptSyntax_$((New-Guid).Guid).ps1" $PowerShellScriptFromClipboard | Out-String | Set-Content -Path $PowerShellScriptPath $Success = $? if($Success) { # Do PowerShell syntax check to temporary PowerShell file $GetCommand = Get-Command -Syntax $PowerShellScriptPath $Success = $? if($Success) { Write-Host "PowerShell syntax is valid`n" -ForegroundColor Green } else { Write-Host "PowerShell syntax is NOT valid`n" -ForegroundColor Red } # Delete PowerShell script from Temp folder Remove-Item -Path $PowerShellScriptPath -Force } else { Write-Host "Something went wrong when saving temporary file: $PowerShellScriptPath" -ForeGroundColor Red Write-Host "PowerShell syntax validation was aborted" -ForeGroundColor Yellow } } else { Write-Host "Clipboard did not contain any text`n" -ForeGroundColor Yellow } } <# .Synopsis This function converts base64 encoded text in clipboard to clear text .DESCRIPTION This function converts base64 encoded text in clipboard to clear text and copies converted text back to clipboard Author: Petri.Paavola@yodamiitti.fi Senior Modern Management Principal Microsoft MVP - Windows and Intune 2023-09-24 https://github.com/petripaavola/ClipboardTools .PARAMETER PassThru PassThru parameter will output converted base64 text to PowerShell pipeline. Usually this is used with saving results to variable. .EXAMPLE ClipboardTools-ConvertFromBase64 .EXAMPLE $ClearTextFromBase64 = ClipboardTools-ConvertFromBase64 -PassThru .INPUTS Reads clipboard base64 text and converts it to clear text .OUTPUTS Converted base64 text is copied to clipboard With parameter -PassThru converted base64 text is sent to PowerShell pipeline. .NOTES None .LINK https://github.com/petripaavola/ClipboardTools #> Function ClipboardTools-ConvertFromBase64 { Param( [Parameter(Mandatory=$false)] [Switch]$PassThru ) [String]$Base64 = Get-Clipboard -Format Text $Success = $? if($Success) { if($Base64) { $ConvertedString = [Text.Encoding]::Utf8.GetString([Convert]::FromBase64String($Base64)) $Success = $? if($Success) { $ConvertedString | Set-Clipboard $Success = $? if($Success) { Write-Host "Converted base64 copied to Clipboard`n" -ForegroundColor Green Write-Host "Converted string from base64:" Write-Host "$ConvertedString`n" -ForeGroundColor Yellow } else { Write-Host "Failed to copy string to Clipboard`n" -Foregroundcolor Red } if($PassThru) { return $ConvertedString } } else { Write-Host "Error converting from base64`n" -ForegroundColor Red } } else { Write-Host "Clipboard did not contain any data to convert`n" -ForeGroundColor Yellow } } else { Write-Host "Clipboard did not contain any data to convert`n" -ForeGroundColor Yellow } } <# .Synopsis This function converts clipboard clear text to base64 encoded string .DESCRIPTION This function converts clipboard clear text to base64 encoded string and copies converted base64 string back to clipboard Author: Petri.Paavola@yodamiitti.fi Senior Modern Management Principal Microsoft MVP - Windows and Intune 2024-09-14 https://github.com/petripaavola/ClipboardTools .PARAMETER PassThru PassThru parameter will output converted base64 string PowerShell pipeline. Usually this is used with saving results to variable. .EXAMPLE ClipboardTools-ConvertToBase64 .EXAMPLE $Base64String = ClipboardTools-ConvertToBase64 -PassThru .INPUTS Reads clipboard text and converts it to base64 string .OUTPUTS Converted base64 string is copied to clipboard With parameter -PassThru converted base64 sting is sent to PowerShell pipeline. .NOTES None .LINK https://github.com/petripaavola/ClipboardTools #> Function ClipboardTools-ConvertToBase64 { Param( [Parameter(Mandatory=$false)] [Switch]$PassThru ) [String]$Text = Get-Clipboard -Format Text $Success = $? if($Success) { if($Text) { # Convert the text to bytes using UTF8 encoding $bytes = [System.Text.Encoding]::UTF8.GetBytes($text) # Convert the bytes to a base64 string $base64String = [System.Convert]::ToBase64String($bytes) $Success = $? if($Success) { $base64String | Set-Clipboard $Success = $? if($Success) { Write-Host "Converted base64 copied to Clipboard`n" -ForegroundColor Green Write-Host "Converted base64 string:" Write-Host "$base64String`n" -ForeGroundColor Yellow } else { Write-Host "Failed to copy base64 to Clipboard`n" -Foregroundcolor Red } if($PassThru) { return $base64String } } else { Write-Host "Error converting text to base64`n" -ForegroundColor Red } } else { Write-Host "Clipboard did not contain any data to convert`n" -ForeGroundColor Yellow } } else { Write-Host "Clipboard did not contain any data to convert`n" -ForeGroundColor Yellow } } <# .Synopsis This function converts a clipboard string to a hexadecimal representation. .DESCRIPTION This function retrieves text from the clipboard and converts it to a hexadecimal string using either UTF-8 or UTF-16 encoding. It allows for specific output formats such as comma-separated values or a format suitable for Windows registry (Regedit). The converted hexadecimal string is copied back to the clipboard. Author: Petri.Paavola@yodamiitti.fi Senior Modern Management Principal Microsoft MVP - Windows and Intune 2024-09-14 https://github.com/petripaavola/ClipboardTools .PARAMETER UTF8 Converts the string to a hexadecimal string using UTF-8 encoding. .PARAMETER UTF16 Converts the string to a hexadecimal string using UTF-16 encoding (default). .PARAMETER CommaSeparated Outputs the hexadecimal string as a comma-separated string. .PARAMETER Regedit Outputs the hexadecimal string in a format suitable for Windows registry, prepending 'hex(2):' to the output. .EXAMPLE ClipboardTools-ConvertStringToHex -UTF8 .EXAMPLE ClipboardTools-ConvertStringToHex -UTF16 -CommaSeparated .EXAMPLE ClipboardTools-ConvertStringToHex -Regedit .INPUTS Reads clipboard text and converts it to a hexadecimal string. .OUTPUTS Converted hexadecimal string is copied to the clipboard. .NOTES If no encoding is specified, UTF-16 will be used by default. .LINK https://github.com/petripaavola/ClipboardTools #> function ClipboardTools-ConvertStringToHex { [CmdletBinding(DefaultParameterSetName = "Default")] Param ( [switch]$UTF8, [switch]$UTF16, [Parameter(ParameterSetName = "CommaSeparated")] [switch]$CommaSeparated, [Parameter(ParameterSetName = "Regedit")] [switch]$Regedit ) # Force UTF16 if -Regedit is specified if ($Regedit) { $UTF16 = $true $UTF8 = $false # Disable UTF8 in case both are specified } # Get the string from clipboard [String]$String = Get-Clipboard # If the clipboard is empty, notify the user and exit if (-not $String) { Write-Host "Empty clipboard" return } # Convert the string to bytes based on encoding if ($UTF16) { Write-Host "Use UTF16 hex conversion" $bytes = [System.Text.Encoding]::Unicode.GetBytes($String) } elseif ($UTF8) { Write-Host "Use UTF8 hex conversion" $bytes = [System.Text.Encoding]::UTF8.GetBytes($String) } else { Write-Host "Encoding not specified, defaulting to UTF16 hex conversion" # Default to UTF16 if neither option is provided $bytes = [System.Text.Encoding]::Unicode.GetBytes($String) } # Convert bytes to hex string $hexString = $bytes | ForEach-Object { "{0:X2}" -f $_ } # Handle parameter sets (either CommaSeparated or Regedit but not both) switch ($PSCmdlet.ParameterSetName) { "CommaSeparated" { Write-Host "Create commaseparated hex string" $hexString = $hexString -join ',' } "Regedit" { Write-Host "Create regedit compatible hex string" # Join hex bytes with a comma and prepend 'hex(2):' $hexString = 'hex(2):' + ($hexString -join ',') } default { $hexString = $hexString -join '' } } # Output the hex string to the clipboard $hexString | Set-Clipboard $Success = $? if($Success) { Write-Host "" Write-Host "Hex string copied to clipboard" -Foregroundcolor Green Write-Host "$hexString`n" -ForegroundColor Yellow } else { Write-Host "Failed to copy hex string to Clipboard`n" -Foregroundcolor Red } } <# .Synopsis This function converts a hexadecimal string from the clipboard back to its original text representation. .DESCRIPTION This function retrieves a hexadecimal string from the clipboard, cleans it by removing unwanted characters, and converts it into a readable text string. It detects the encoding (UTF-8 or UTF-16LE) based on byte patterns and outputs the decoded string back to the clipboard. Author: Petri.Paavola@yodamiitti.fi Senior Modern Management Principal Microsoft MVP - Windows and Intune 2024-09-14 https://github.com/petripaavola/ClipboardTools .EXAMPLE ClipboardTools-ConvertHexToString .INPUTS Reads hexadecimal string from the clipboard and converts it into a readable text string. .OUTPUTS The converted text string is copied back to the clipboard. .NOTES This function automatically detects whether the clipboard contents are in UTF-8 or UTF-16LE encoding and decodes accordingly. The function handles single-line and multi-line clipboard content and removes unnecessary characters. .LINK https://github.com/petripaavola/ClipboardTools #> function ClipboardTools-ConvertHexToString { # Yes, this function is heavily influenced by ChatGPT # Retrieve the hex string from clipboard $hexStringFromClipboard = Get-Clipboard if(-not $hexStringFromClipboard) { Write-Host "Empty clipboard" return } Write-Host "Trying to convert Clipboard Hex to String" # Initialize an empty string to hold the cleaned hex $hexString = "" Try { # Check if the clipboard content is an array (multiple lines) if ($hexStringFromClipboard -is [array]) { # Loop through each line in the clipboard content foreach ($line in $hexStringFromClipboard) { # Remove unnecessary characters like '\', newlines, and spaces $cleanedLine = $line -replace '\\', '' -replace '\s+', '' -replace ',', '' # Remove extra information before the actual hex string (e.g., "UninstallString"=hex(2):) if ($cleanedLine -match ':') { $cleanedLine = $cleanedLine.Split(':')[1] } # Append the cleaned hex to the main hex string $hexString += $cleanedLine } } else { # If it's a single string, perform similar cleanup $hexString = $hexStringFromClipboard -replace '\\', '' -replace '\s+', '' -replace ',', '' # Remove extra information before the actual hex string (if applicable) if ($hexString -match ':') { $hexString = $hexString.Split(':')[1] } } # Convert the cleaned hex string into a byte array $bytes = @() for ($i = 0; $i -lt $hexString.Length; $i += 2) { $hexChar = $hexString.Substring($i, 2) $bytes += [convert]::ToByte($hexChar, 16) } # Detect encoding based on byte patterns function Detect-Encoding { param ([byte[]]$byteArray) # Check if the byte array contains alternating 00s, indicating UTF-16LE $isUtf16 = $true for ($i = 1; $i -lt $byteArray.Length; $i += 2) { if ($byteArray[$i] -ne 0) { $isUtf16 = $false break } } if ($isUtf16) { return 'UTF-16LE' } # UTF-8 detection is trickier, so as a fallback we'll assume UTF-8 return 'UTF-8' } # Determine the encoding $encoding = Detect-Encoding $bytes Write-Host "Detected encoding: $encoding" # Convert based on the detected encoding if ($encoding -eq 'UTF-16LE') { $decodedString = [System.Text.Encoding]::Unicode.GetString($bytes) } else { $decodedString = [System.Text.Encoding]::UTF8.GetString($bytes) } # Set the result back to the clipboard $decodedString | Set-Clipboard $Success = $? if($Success) { Write-Host "" Write-Host "Decoded string copied to Clipboard:" -Foregroundcolor Green Write-Host "$decodedString`n" -ForegroundColor Yellow } else { Write-Host "Failed to copy hex string to Clipboard`n" -Foregroundcolor Red } } catch { Write-Host "" Write-Host "Error converting Clipboard (Hex?) content to String" -ForegroundColor Red } } <# .Synopsis This function converts Intune report format JSON from clipboard to "objectified" data .DESCRIPTION This function converts Intune report format JSON from clipboard to "objectified" data and then sets converted JSON report back to clipboard With parameter -PassThru processed JSON report data is sent to PowerShell pipeline where you can for example save data to variable Author: Petri.Paavola@yodamiitti.fi Senior Modern Management Principal Microsoft MVP - Windows and Intune 2023-09-24 https://github.com/petripaavola/ClipboardTools .EXAMPLE ClipboardTools-ObjectifyIntuneJsonReport .EXAMPLE $IntuneReport = ClipboardTools-ObjectifyIntuneJsonReport -PassThru .INPUTS Reads clipboard (Intune report format) JSON data .OUTPUTS With parameter -PassThru processed Intune report JSON data is sent to PowerShell pipeline. .NOTES None .LINK https://github.com/petripaavola/ClipboardTools #> function ClipboardTools-ObjectifyIntuneJsonReport { Param( [Parameter(Mandatory=$false)] [Switch]$PassThru ) # Read Clipboard text $ClipboardJSON = Get-Clipboard -Format Text if($ClipboardJSON) { try { $json = $ClipboardJSON | ConvertFrom-Json $Success = $? if($Success) { Write-Host "Clipboard text has valid JSON syntax" -ForegroundColor Green if($Json.Schema) { $JsonSchema = $Json.Schema } else { Write-Host "Warning: Did not detect valid Intune/Graph API report formatted JSON data" -ForeGroundColor Yellow Write-Host "Warning: Schema property missing." -ForeGroundColor Yellow return $null } if($Json.Values) { $JsonValues = $Json.Values } else { Write-Host "Warning: Did not detect valid Intune/Graph API report formatted JSON data" Write-Host "Warning: Values property missing." -ForeGroundColor Yellow return $null } # Create empty arrayList # ArrayList should be quicker if we have a huge data set # because using array and += always creates new array with added array value/object $JsonObjectArrayList = New-Object -TypeName "System.Collections.ArrayList" # Convert json data to PowerShell objects in $JsonObjectArrayList foreach($Value in $JsonValues) { # We use this counter to get property name value from Schema array $i=0 # Add values to HashTable which we use to create custom PowerShell object later $ValuesHashTable = @{} foreach($ValueEntry in $Value) { # Create variables $PropertyName = $JsonSchema[$i].Column $ValuePropertyType = $JsonSchema[$i].PropertyType $PropertyValue = $ValueEntry -as $ValuePropertyType # Add hashtable entry $ValuesHashTable.add($PropertyName, $PropertyValue) # Create PowerShell custom object from hashtable $CustomObject = new-object psobject -Property $ValuesHashTable $i++ } # Add custom PowerShell object to ArrayList $JsonObjectArrayList.Add($CustomObject) | Out-Null } # Set processed report JSON data to clipboard $JsonObjectArrayList | ConvertTo-Json -Depth 10 | Set-Clipboard if($PassThru) { $JsonObjectArrayList } } else { Write-Host "Clipboard text is NOT valid JSON syntax" -ForegroundColor Red } } catch { Write-Host "Clipboard text is NOT valid JSON syntax" -ForegroundColor Red } } else { Write-Host "Clipboard did not contain any text`n" -ForeGroundColor Yellow } } <# .Synopsis This function converts Edge Debugger Save as PowerShell -script to "real" PowerShell script syntax .DESCRIPTION This function converts Edge Debugger Save as PowerShell -script to "real" PowerShell script syntax This function version creates Microsoft.Graph.Authentication PowerShell Module compatible code. "Real" PowerShell syntax means real PowerShell commands you can use in your scripts. Commands will do same Graph API call which you copied from Edge debugger data. Converted commands are set to clipboard so you can paste actual PowerShell code to your code editor. And you can also run PowerShell commands in PowerShell console. Prerequisite for created PowerShell code to work you need to install Microsoft Graph Authentication PowerShell Module You can install module with command: Install-Module -Name Microsoft.Graph.Authentication -Scope CurrentUser Author: Petri.Paavola@yodamiitti.fi Senior Modern Management Principal Microsoft MVP - Windows and Intune 2024-09-14 https://github.com/petripaavola/ClipboardTools .EXAMPLE ClipboardTools-EdgeDebuggerMGGraphPowerShellScript .INPUTS Reads clipboard text (Edge Debugger -> Save as PowerShell -data) .OUTPUTS "PowerShell script ready" PowerShell code is sent to Clipboard .NOTES None .LINK https://github.com/petripaavola/ClipboardTools #> Function ClipboardTools-EdgeDebuggerMGGraphPowerShellScript { # We will get array of strings $Clipboard = Get-Clipboard -Format Text if(-not $Clipboard) { Write-Host "Clipboard did not contain any text`n" -ForeGroundColor Yellow return $null } # Remove escapes $Clipboard = $Clipboard.Replace('`','') # Find Invoke-WebRequest string $InvokeWebRequest = $Clipboard | Where-Object { $_ -like "Invoke-WebRequest *" } # Find uri $regex = '^Invoke-WebRequest.*-Uri "(.*)".*$' if($InvokeWebRequest -match $regex) { $Uri = $Matches[1] # Add escapes before $ character $Uri = $Uri.Replace('$','`$') } else { $Uri=$null Write-Host "Could not parse Uri from Edge Debugger PowerShell copy" -ForegroundColor Red return $null } # Extract Method (=POST, PATCH, PUT, DELETE) $MethodString = $Clipboard | Where-Object { $_ -like "-Method *" } if($MethodString) { $regex = '^-Method "(.*)".*$' if($MethodString -match $regex) { $Method = $Matches[1] } else { # There is no Method parameter with Get method $Method="Get" } } else { # There is no Method parameter with Get method $Method="Get" } # Extract body json $BodyString = $Clipboard | Where-Object { $_ -like "-Body *" } if($BodyString) { # Examples # -Body ([System.Text.Encoding]::UTF8.GetBytes("{`"@odata.type`":`"#microsoft.graph.winGetApp`"}}")) if(($BodyString -match '^-Body "(.*)".*$') -or ($BodyString -match '^-Body \(\[System.Text.Encoding\]::UTF8\.GetBytes\("(.*)"\)\)$')) { $Body = $Matches[1] $BodyJson = $Body | ConvertFrom-Json | ConvertTo-Json -Depth 10 # Add escapes to $ characters $BodyJson = $BodyJson.Replace('$','`$') } else { # There is no Body parameter with Get method $Body=$null } } else { # There is no Body parameter with Get method $Body=$null } # DEBUG #Write-Host "Uri=$Uri" #Write-Host "Method=$Method" #Write-Host "Body=$Body" #Write-Host "BodyJson=$BodyJson" if($BodyJson){ # Method is POST, PUT, PATCH or DELETE with Body information $Paste = @" # Connect to Graph API using Microsoft Graph module # Install Microsoft.Graph.Authentication module with command # Install-Module -Name Microsoft.Graph.Authentication -Scope CurrentUser #Connect-MgGraph Connect-MgGraph -Scopes "DeviceManagementManagedDevices.Read.All", "DeviceManagementApps.Read.All", "DeviceManagementConfiguration.Read.All", "User.Read.All", "Group.Read.All", "GroupMember.Read.All", "Directory.Read.All" `$Uri = `"$Uri`" `$Body = `@`" $BodyJson `"`@ # Note! There seems to be either a bug or a feature with POST requests with Invoke-MgGraphRequest # In some testings command succeeds but does not return anything to PowerShell pipeline # but with -Debug option you can see that the data has been fetched from Graph API # For now one workaround is to save data to text file which we'll do here # Get data from Graph API # Original request #`$MgGraphRequest = Invoke-MgGraphRequest -Uri `$Uri -Body `$Body.ToString() -Method '$Method' -OutputType PSObject # Workaround to save data to random named text file first with parameter -OutputFilePath `$OutputFilePath = `"`$(`$pwd.path)/MgGraphRequest_`$(Get-Random).json`" `$MgGraphRequest = Invoke-MgGraphRequest -Uri `$Uri -Body `$Body.ToString() -Method '$Method' -OutputFilePath `$OutputFilePath # Read and convert json data from temporary text file `$MgGraphRequest = Get-Content `$OutputFilePath -Raw | ConvertFrom-Json # Remove temporary file Remove-Item -Path `$OutputFilePath if(`$MgGraphRequest) { # Print results # Usually you want to check values from `$MgGraphRequest.value Write-Host `"Print variable MgGraphRequest values:`" `$MgGraphRequest } else { Write-Host "Did not get any results from Graph API!" -ForegroundColor Yellow } "@ } else { # Method is GET or DELETE without Body in request $Paste = @" # Connect to Graph API using Microsoft Graph module # Install Microsoft.Graph.Authentication module with command # Install-Module -Name Microsoft.Graph.Authentication -Scope CurrentUser #Connect-MgGraph Connect-MgGraph -Scopes "DeviceManagementManagedDevices.Read.All", "DeviceManagementApps.Read.All", "DeviceManagementConfiguration.Read.All", "User.Read.All", "Group.Read.All", "GroupMember.Read.All", "Directory.Read.All" `$Uri = `"$Uri`" # Get data from Graph API `$MgGraphRequest = Invoke-MgGraphRequest -Uri `$Uri -Method '$Method' -OutputType PSObject if(`$MgGraphRequest) { # Print results # Usually you want to check values from `$MgGraphRequest.value Write-Host `"Print variable MgGraphRequest values:`" `$MgGraphRequest } else { Write-Host "Did not get any results from Graph API!" -ForegroundColor Yellow } "@ } # DEBUG #Write-Host "Paste=$Paste" # Set edited info back to Clipboard $Paste | Set-Clipboard } |