TM-RandomUtility.psm1
using namespace System using namespace System.IO using namespace System.Collections.Generic function Get-ExceptionTypeName { <# .SYNOPSIS Returns the exception type name that occurred when executing a script block or command. .DESCRIPTION This function executes the provided command or script block and returns the full name of the exception type that occurred during execution. Only use this function if you know the exception will not cause further damage by running again. .PARAMETER Command The command to execute .PARAMETER ScriptBlock The script block to execute .EXAMPLE Get-HelpFromType -TypeNames (Get-ExceptionTypeName -Command 'Write-Error "test"') .OUTPUTS If the provided command causes an exception then the exception's typename will be returned. If the provided command does NOT cause an exception then nothing is returned. #> [CmdletBinding(DefaultParameterSetName = 'string')] [OutputType([Void], [string])] param ( [Parameter( Mandatory, ValueFromPipeline, ValueFromRemainingArguments, ParameterSetName = 'string' )] [string]$Command, [Parameter( Mandatory, ValueFromPipeline, ValueFromRemainingArguments, ParameterSetName = 'ScriptBlock' )] [scriptblock]$ScriptBlock ) [ScriptBlock]$SB = switch ($PSCmdlet.ParameterSetName) { 'string' { [ScriptBlock]::Create($Command) } 'ScriptBlock' { $ScriptBlock } } $ErrorActionPreference = 'Stop' try { $SB.Invoke() | Out-Null } catch { return $_.Exception.GetType().FullName } } function Get-HelpFromType { <# .SYNOPSIS Opens the documentation for .NET types in a web browser. .DESCRIPTION This function opens the official Microsoft documentation for .NET types in the default web browser. .PARAMETER Objects Array of objects to determine the type of and fetch the documentation for. .EXAMPLE Get-HelpFromType -TypeNames @($Object1.GetType().FullName, ($Error[-1].Exception.GetType().FullName)) .EXAMPLE Get-HelpFromType -Types $Error[-1].Exception.GetType() #> [CmdletBinding(DefaultParameterSetName = 'TypeNames')] [OutputType([Void])] param ( [Parameter( Mandatory, ValueFromPipeline, ValueFromRemainingArguments, ParameterSetName = 'TypeNames' )] [string[]]$TypeNames, [Parameter( Mandatory, ValueFromPipeline, ValueFromRemainingArguments, ParameterSetName = 'Types' )] [Type[]]$Types ) process { [string[]]$InputTypes = switch ($PSCmdlet.ParameterSetName) { 'Types' { [List[string]]$typeList = [List[string]]::new() foreach ($Type in $Types) { $typeList.Add($Type.FullName) } $typeList.ToArray() } 'TypeNames' { $TypeNames } } foreach ($typeName in $InputTypes) { Start-Process -FilePath "https://docs.microsoft.com/en-us/dotnet/api/$typeName" } } } function New-Timer { <# .SYNOPSIS Starts a new timer. .DESCRIPTION This function creates and starts a new stopwatch timer. #> [CmdletBinding()] [OutputType([Diagnostics.Stopwatch])] param () return [Diagnostics.Stopwatch]::StartNew() } function Test-ApplicationExistsInPath { <# .SYNOPSIS Uses Get-Command to see whether the $ApplicationName exists in the path. #> [CmdletBinding()] [OutputType([boolean])] param( [Parameter(Mandatory)] [string]$ApplicationName ) return ($null -ne (Get-Command $ApplicationName -CommandType Application -ErrorAction Ignore)) } function Write-RandomBytesToFile { <# .SYNOPSIS Writes random bytes to a file. .DESCRIPTION This function writes random bytes to a file until that file has reached the specified fileByteSize. If the file is already greater than fileByteSize then the function exits early. .PARAMETER fileByteSize The desired file size in bytes .PARAMETER fileName The name of the file to write to, default is 'temp.rnd' .PARAMETER directoryPath The directory path where the file will be created or updated, default is the current directory #> [CmdletBinding()] [OutputType([Void])] param ( [Parameter(Mandatory)] [long]$fileByteSize, [Parameter(Mandatory = $false)] [string]$fileName = 'temp.rnd', [Parameter(Mandatory = $false)] [string]$directoryPath = [Environment]::CurrentDirectory ) [string]$filePath = Join-Path -Path $directoryPath -ChildPath $fileName [Random]$rnd = [Random]::New() [IO.FileInfo]$file = [IO.FileInfo]::New($filePath); if ($file.Length -ge $fileByteSize) { Write-Host "File size for '$($file.FullName)' already meets or exceeds $fileByteSize" return } [IO.FileStream]$outputStream try { $outputStream = [IO.File]::Open($file.FullName, [IO.FileMode]::OpenOrCreate) $outputStream.Seek(0, [IO.SeekOrigin]::End) | Out-Null [long]$bytesWritten = $file.Length do { [byte[]]$bytes = [byte[]]::New( (. { if ($fileByteSize -gt ($bytesWritten + 1024)) { 1024 } else { [int]($fileByteSize - $bytesWritten) } }) ) $rnd.NextBytes($bytes) $outputStream.Write($bytes, 0, $bytes.Length) $bytesWritten += $bytes.Length } while ($bytesWritten -lt $fileByteSize) Write-Host "Wrote $bytesWritten bytes to '$($file.FullName)'. FileSize: $fileByteSize" } finally { if ($null -ne $outputStream) { $outputStream.Dispose() } } } |