Routines.psm1
function Read-Choice { <# .SYNOPSIS Display a prompt like PowerShell does. .DESCRIPTION Make a Powershell style prompt. You must provide the same number of options and help messages. The function returns an integer, the selected options. .EXAMPLE PS C:\> Read-Choice -Title 'Do you want to continue ?' -Prompt 'Answer yes or no' Do you want to continue ? Answer yes or no [Y] Yes [N] No [?] Help (default is "Y"): .EXAMPLE PS C:\> Read-Choice -Title 'Do you want to continue ?' -Prompt 'Answer yes or no' -Options '&Yes','&No','Yes for &all','N&o for all' -HelpMessage 'Say yes','Say No','Say allways yes','Say allways no' Do you want to continue ? Answer yes or no [Y] Yes [N] No [?] Help (default is "Y"): .LINK https://dawan.fr #> [CmdletBinding()]param( [parameter(Mandatory)] [string]$Title, [parameter(Mandatory)] [string]$Prompt, [string[]]$Options=@('&Yes','&No'), [string[]]$HelpMessages=@('','') ) if ($Options.Count -ne $HelpMessages.Count) { Throw 'Please provide as much Options as HelpMessages' } $tabOptions = @() $i=0 foreach ($opt in $Options) { $tabOptions += New-Object System.Management.Automation.Host.ChoiceDescription $opt, $HelpMessages[$i] $i++ } $Choices = [System.Management.Automation.Host.ChoiceDescription[]] ($tabOptions) return $host.ui.PromptForChoice($Title,$Prompt,$Choices,0) } function Read-PopUp { <# .SYNOPSIS Display a popup. .DESCRIPTION Provides a wrapper for MessageBox. Returns the value of the selected button. .EXAMPLE PS C:\> Read-PopUp -Title Information -Message 'information to display' Ok .EXAMPLE PS C:\> Read-PopUp -Title Question -Message 'Continue ?' -Buttons YesNo No .EXAMPLE PS C:\> Read-PopUp -Title Question -Message "What to do?" -Buttons AbortRetryIgnore -Icon Error -DefaultButton Button3 Retry .LINK https://dawan.fr #> [CmdletBinding()]param( [parameter(Mandatory)] [string]$Title, [parameter(Mandatory)] [string]$Message, [ValidateSet('Ok', 'AbortRetryIgnore','OkCancel','RetryCancel','YesNo','YesNoCancel')] [string]$Buttons='Ok', [ValidateSet('Asterisk','Error','Exclamation','Hand','Information','None','Question','Stop','Warning')] [string]$Icon='None', [ValidateSet('Button1','Button2','Button3')] [string]$DefaultButton='Button1' ) Add-Type -AssemblyName "System.Windows.Forms" $dlg = [System.Windows.Forms.MessageBox] $btn = [System.Windows.Forms.MessageBoxButtons]::$Buttons $icn = [System.Windows.Forms.MessageBoxIcon]::$Icon $dfb = [System.Windows.Forms.MessageBoxDefaultButton]::$DefaultButton return $dlg::Show($Message, $Title, $btn, $icn, $dfb) } function Remove-Diacritics { <# .SYNOPSIS Function Designed for remove special characters and provides a string usable for login. .LINK https://dawan.fr #> [CmdletBinding()]param( [parameter(Mandatory)] [string]$String ) return [Text.Encoding]::ASCII.GetString([Text.Encoding]::GetEncoding("Cyrillic").GetBytes($String)) } function Clear-String { <# .SYNOPSIS Function designed for remove special characters and provides a string usable for login. .LINK https://dawan.fr #> param( [parameter(Mandatory)] [string]$String, [string[]]$DeletedChars = @('-',' ',"'"), [string[]]$ReplacedChars = @('œ','æ'), [string[]]$ReplacedByChars = @('oe','ae'), [switch]$LowerCase, [ValidateRange(1,100)] [byte]$MaxLength = 20 ) foreach ($char in $DeletedChars) { $String = $String -replace $char,'' # opérateur de remplacement } $i = 0 foreach ($char in $ReplacedChars) { $String = $String -replace $char,$ReplacedByChars[$i] $i++ } if ($String.length -gt $MaxLength) { $String = $String.SubString(0, $MaxLength) } if ($LowerCase) { $String = $String.ToLower() } return $String } function Get-Password { <# .SYNOPSIS Function returning a password according to complexity required in AD domain. .DESCRIPTION You can change the numbers of letters, digits and non alpha-numeric characters required. You can modify the sets of allowed characters. .LINK https://dawan.fr #> param( [byte]$NumLetters = 5, [byte]$NumDigits = 2, [byte]$NumNonAlphaNum = 1, [switch]$AsSecureString, [string]$LettersAllowed = 'azertyuiopmlkjhgfdsqwxcvbn', [string]$DigitsAllowed = '0123456789', [string]$NonAlphNumAllowed = ':;,!*$=-' ) $LettersTab = $LettersAllowed -split '' $DigitsTab = $DigitsAllowed -split '' $NonAlphNumTab = $NonAlphNumAllowed -split '' # Tirer au sort dans un tableau : Get-Random $CharTab = $LettersTab | Get-Random -Count $NumLetters -ea Ignore # ea : ErrorAction $CharTab += $DigitsTab | Get-Random -Count $NumDigits -ea Ignore $CharTab += $NonAlphNumTab | Get-Random -Count $NumNonAlphaNum -ea Ignore # Mélanger le tableau : Sort-Objet avec Get-Random $CharTab = $CharTab | Sort-Object {Get-Random} $Password = $CharTab -Join '' # opérateur de rassemblement d'élément de tab if ($AsSecureString) { return (ConvertTo-SecureString $Password -AsPlainText -Force) } else { return $Password } } function Convert-IPtoInt32 () { param ( [parameter(Mandatory=$true)] [ipaddress]$ip ) $octets = ([string]($ip)).split(".") return [uint32]([uint32]$octets[0] * 16777216 + [uint32]$octets[1] * 65536 + [uint32]$octets[2] * 256 + [uint32]$octets[3]) } function Convert-Int32toIP() { param ( [parameter(Mandatory=$true)] [uint32]$int ) return (([math]::truncate($int / 16777216)).tostring() + "." + ([math]::truncate(($int % 16777216) / 65536)).tostring() + "." + ([math]::truncate(($int % 65536) / 256)).tostring() + "." + ([math]::truncate($int % 256)).tostring() ) } function Get-IPv4Range { <# .SYNOPSIS Get the IP addresses in a range .DESCRIPTION Returns an array .EXAMPLE Get-IPrange -start 192.168.8.2 -end 192.168.8.20 .EXAMPLE Get-IPrange -IPv4Address 192.168.8.2 -NetMask 255.255.255.0 .EXAMPLE Get-IPrange -IPv4Address 192.168.8.3 -CIDRMask 24 -Addressable .LINK https://dawan.fr #> [CmdletBinding(DefaultParameterSetName='mask')] param ( [Parameter(Mandatory=$true, ParameterSetName='range', Position=0)] [ipaddress]$Start, [Parameter(Mandatory=$true, ParameterSetName='range', Position=1)] [ipaddress]$End, [Parameter(Mandatory=$true, ParameterSetName='mask', Position=0)] [Parameter(Mandatory=$true, ParameterSetName='cidr', Position=0)] [ipaddress]$IPv4Address, [Parameter(ParameterSetName='mask', Position=1)] [ipaddress]$NetMask = '255.255.255.0', [Parameter(ParameterSetName='cidr', Position=1)] [ValidateRange(0,32)] [uint32]$CIDRMask = 24, [Parameter(ParameterSetName='mask', Position=2)] [Parameter(ParameterSetName='cidr', Position=2)] [switch]$Addressable ) Switch -Regex ($PSCmdlet.ParameterSetName) { 'mask|cidr' { $ipaddr = [Net.IPAddress]::Parse($IPv4Address) if ($PSCmdlet.ParameterSetName -eq 'cidr') { $maskaddr = [Net.IPAddress]::Parse((Convert-Int32toIP -int ([convert]::ToInt64(("1" * $CIDRMask + "0" * (32 - $CIDRMask)), 2)))) } else { $maskaddr = [Net.IPAddress]::Parse($NetMask) } $networkaddr = New-Object net.ipaddress ($maskaddr.address -band $ipaddr.address) $broadcastaddr = New-Object net.ipaddress (([system.net.ipaddress]::parse("255.255.255.255").address -bxor $maskaddr.address -bor $networkaddr.address)) $startaddr = Convert-IPtoInt32 -ip $networkaddr.ipaddresstostring $endaddr = Convert-IPtoInt32 -ip $broadcastaddr.ipaddresstostring } 'range' { $startaddr = Convert-IPtoInt32 -ip $Start $endaddr = Convert-IPtoInt32 -ip $End } } if ($Addressable) { $startaddr++ $endaddr-- } for ($i = $startaddr; $i -le $endaddr; $i++) { Convert-Int32toIP -int $i } } function Get-IPv4Info { <# .SYNOPSIS Returns information about IPv4 address. .DESCRIPTION Returns - class, - type : public, private, multicast or reserved - start ip and end ip .LINK https://dawan.fr .EXAMPLE PS C:\> Get-IPv4Info 192.168.75.2 Class : C Type : Private IPStart : 192.168.0.0 IPEnd : 192.168.255.255 IPAddress : 192.168.75.2 .EXAMPLE PS C:\> Get-IPv4Info 12.45.123.201 Class : A Type : Public IPStart : 0.0.0.0 IPEnd : 126.255.255.255 IPAddress : 12.45.123.201 #> [CmdletBinding()] param( [parameter(Mandatory=$true)] [ipaddress]$IPAddress ) $networks = @( [PSCustomObject] @{end=167772159; Class='A'; Type='Public'; IPStart='0.0.0.0'; IPEnd='126.255.255.255'}, # 0.0.0.0 - 9.255.255.255 [PSCustomObject] @{end=184549375; Class='A'; Type='Private'; IPStart='10.0.0.0'; IPEnd='10.255.255.255'}, # 10.0.0.0/8 [PSCustomObject] @{end=2130706431; Class='A'; Type='Public'; IPStart='0.0.0.0'; IPEnd='126.255.255.255'}, # 11.0.0.0 - 126.255.255.255 [PSCustomObject] @{end=2147483647; Class='-'; Type='Localhost'; IPStart='127.0.0.0'; IPEnd='127.255.255.255'}, # 127.0.0.0/8 [PSCustomObject] @{end=2886729727; Class='B'; Type='Public'; IPStart='128.0.0.0'; IPEnd='191.255.255.255'}, # 128.0.0.0 - 172.15.255.255 [PSCustomObject] @{end=2887778303; Class='B'; Type='Private'; IPStart='172.16.0.0'; IPEnd='172.31.255.255'}, # 172.16.0.0/12 [PSCustomObject] @{end=3221225471; Class='B'; Type='Public'; IPStart='128.0.0.0'; IPEnd='191.255.255.255'}, # 172.32.0.0 - 191.255.255.255 [PSCustomObject] @{end=3232235519; Class='C'; Type='Public'; IPStart='192.0.0.0'; IPEnd='223.255.255.255'}, # 192.0.0.0 - 192.167.255.255 [PSCustomObject] @{end=3232301055; Class='C'; Type='Private'; IPStart='192.168.0.0'; IPEnd='192.168.255.255'}, # 192.168.0.0/16 [PSCustomObject] @{end=3758096383; Class='C'; Type='Public'; IPStart='192.0.0.0'; IPEnd='223.255.255.255'}, # 192.169.0.0 - 223.255.255.255 [PSCustomObject] @{end=4026531839; Class='D'; Type='Multicast'; IPStart='224.0.0.0'; IPEnd='239.255.255.255'}, # 224.0.0.0 - 239.255.255.255 [PSCustomObject] @{end=4294967295; Class='E'; Type='Reserved'; IPStart='240.0.0.0'; IPEnd='255.255.255.255'} # 240.0.0.0 - 255.255.255.255 ) $ip = Convert-IPtoInt32 $IPAddress $net = $networks | Where-Object end -ge $ip | Select-Object -First 1 | Select-Object Class,Type,IpStart,IPEnd $net | Add-Member -Name IPAddress -Value $IPAddress -MemberType NoteProperty return $net } New-Alias -Name gir -Value Get-IPv4Range function Test-ICMP { <# .SYNOPSIS Faster ping .DESCRIPTION Ping with a timeout in milliseconds customizable .PARAMETER ComputerName IP or hostname .PARAMETER Network Network : X.X.X.X/CIDR. eg : 192.168.1.0/24 .LINK https://dawan.fr .EXAMPLE Test-MyTestFunction -Verbose Explanation of the function or its result. You can include multiple examples with additional .EXAMPLE lines #> [cmdletBinding(DefaultParameterSetName='computer')] param( [parameter(Mandatory=$true, ParameterSetName='computer', Position=0)] [string]$ComputerName, [parameter(Mandatory=$true, ParameterSetName='network', Position=0)] [ValidateScript({ [boolean]([ipaddress]($_.Split('/')[0])) -and ([byte]($_.Split('/')[1] -in 0..32)) })] [string]$Network, [parameter(Position=1)] [uint32]$Count=4, [parameter(Position=2)] [ValidateRange(1, 10000)] [uint32]$Timeout=200, [parameter(Position=3)] [ValidateRange(1, 128)] [byte]$TTL=128, [parameter(Position=4)] [ValidateRange(20,980)] [uint16]$Length = 32, [parameter(ParameterSetName='computer', Position=5)] [Switch]$Quiet, [parameter(ParameterSetName='network', Position=5)] [Switch]$Up ) $result = $false if ($Count -eq 0) { $Count = 2GB } $ps = New-Object System.Net.NetworkInformation.Ping $data = "aquickbrownfoxjumpedoverthelazydog" $buffer = [System.Text.Encoding]::ASCII.GetBytes($data) $po = New-Object System.Net.NetworkInformation.PingOptions $po.DontFragment = $true $po.Ttl = $TTL switch ($PSCmdlet.ParameterSetName) { 'computer' { for ($i = 1; $i -le $Count; $i++) { $reply = $ps.Send($ComputerName, $Timeout, $buffer, $po) if (-not $Quiet) { Write-Output ([PSCustomObject]@{ PSTypeName = 'My.ICMPResult' Number = $i Address = $reply.Address Status = $reply.Status Time = $reply.RoundtripTime TTL = $reply.Options.Ttl Data = $reply.Buffer.Length }) } else { if ($reply.Status -eq 'Success') { $s = $true } else { $s = $false } $result = $result -or $s } } if ($Quiet) { return $result } } 'network' { $target = Get-IPv4Range -IPv4Address ($Network.Split('/')[0]) -CIDRMask ($Network.Split('/')[1]) -Addressable foreach($ComputerName in $target) { $result = @() for ($i = 1; $i -le $Count; $i++) { $reply = $ps.Send($ComputerName, $Timeout, $buffer, $po) $result += ([PSCustomObject]@{ PSTypeName = 'My.ICMPResult' Number = $i Address = $reply.Address Status = $reply.Status Time = $reply.RoundtripTime TTL = $reply.Options.Ttl Data = $reply.Buffer.Length }) } $PingSuccess = $result | Where-Object status -eq 'success' | Measure-Object Time -Average -Minimum -Maximum $Succeeded = [boolean]($PingSuccess.Count) $PercentSucceeded = [int]($PingSuccess.Count * 100 / $Count) if (($Up -and $Succeeded) -or (-not $Up)) { Write-Output ([PSCustomObject]@{ PSTypeName = 'My.ICMPNetworkResult' IPAddress = $ComputerName Succeeded = $Succeeded PercentSucceeded = $PercentSucceeded AverageTime = [int]($PingSuccess.Average) MinTime = $PingSuccess.Minimum MaxTime = $PingSuccess.Maximum DetailedInfo = $result }) } } } } } |