├── .gitignore ├── Convert-EmlFile.ps1 ├── Export-Registry.ps1 ├── Get-ElapsedTime.ps1 ├── Get-TimerStatus.ps1 ├── Get-UniqueUPN.ps1 ├── LICENSE ├── New-ApiRequest.ps1 ├── New-StringConversion.ps1 ├── New-Timer.ps1 ├── README.md ├── Stop-Timer.ps1 ├── Test-IsEmail.ps1 ├── Test-IsGuid.ps1 ├── Test-IsRegistryKey.ps1 ├── Test-IsValidDn.ps1 └── Test-UpnExist.ps1 /.gitignore: -------------------------------------------------------------------------------- 1 | *.TempPoint.ps1 2 | -------------------------------------------------------------------------------- /Convert-EmlFile.ps1: -------------------------------------------------------------------------------- 1 | function Convert-EmlFile 2 | { 3 | <# 4 | .SYNOPSIS 5 | Function will parse an eml files. 6 | 7 | .DESCRIPTION 8 | Function will parse eml file and return a normalized object that can be used to extract infromation from the encoded file. 9 | 10 | .PARAMETER EmlFileName 11 | A string representing the eml file to parse. 12 | 13 | .EXAMPLE 14 | PS C:\> Convert-EmlFile -EmlFileName 'C:\Test\test.eml' 15 | 16 | .OUTPUTS 17 | System.Object 18 | #> 19 | [CmdletBinding()] 20 | [OutputType([object])] 21 | param 22 | ( 23 | [Parameter(Mandatory = $true)] 24 | [ValidateNotNullOrEmpty()] 25 | [string] 26 | $EmlFileName 27 | ) 28 | 29 | # Instantiate new ADODB Stream object 30 | $adoStream = New-Object -ComObject 'ADODB.Stream' 31 | 32 | # Open stream 33 | $adoStream.Open() 34 | 35 | # Load file 36 | $adoStream.LoadFromFile($EmlFileName) 37 | 38 | # Instantiate new CDO Message Object 39 | $cdoMessageObject = New-Object -ComObject 'CDO.Message' 40 | 41 | # Open object and pass stream 42 | $cdoMessageObject.DataSource.OpenObject($adoStream, '_Stream') 43 | 44 | return $cdoMessageObject 45 | } -------------------------------------------------------------------------------- /Export-Registry.ps1: -------------------------------------------------------------------------------- 1 | function Export-Registry 2 | { 3 | <# 4 | .SYNOPSIS 5 | Export registry item properties. 6 | 7 | .DESCRIPTION 8 | Export item properties for a given registry key. 9 | 10 | By default results will be written to the pipeline unless the -ExportFormat parameter is used. 11 | 12 | .PARAMETER KeyPath 13 | A string representing the Key(s) to export in the PsDrive format IE: HKCU:\SOFTWARE\TestSoftware 14 | 15 | .PARAMETER ExportFormat 16 | A string representing the format to use for the export. 17 | 18 | Possible values are: 19 | 20 | - CSV 21 | - XML 22 | 23 | PArameter is used in conjunction with the ExportPath paramter. 24 | 25 | .PARAMETER ExportPath 26 | A string representing the path where keys should be exported. 27 | 28 | .PARAMETER NoBinaryData 29 | When parameter is specified any binary data present in the registry key is removed. 30 | 31 | .EXAMPLE 32 | PS C:\> Export-RegistryNew -KeyPath 'HKCU:\SOFTWARE\TestSoftware' 33 | 34 | .NOTES 35 | Additional information about the function. 36 | #> 37 | 38 | [CmdletBinding(DefaultParameterSetName = 'PrintOnly')] 39 | param 40 | ( 41 | [Parameter(ParameterSetName = 'PrintOnly', 42 | Mandatory = $true, 43 | ValueFromPipeline = $true, 44 | ValueFromPipelineByPropertyName = $true, 45 | Position = 0, 46 | HelpMessage = 'Enter a registry path using the PSDrive format (IE: HKCU:\SOFTWARE\TestSoftware')] 47 | [Parameter(ParameterSetName = 'Export', 48 | Mandatory = $true)] 49 | [ValidateNotNullOrEmpty()] 50 | [Alias('PSPath')] 51 | [string[]] 52 | $KeyPath, 53 | [Parameter(ParameterSetName = 'Export', 54 | Mandatory = $true)] 55 | [ValidateSet('xml', 'csv', 'reg', IgnoreCase = $true)] 56 | [ValidateNotNullOrEmpty()] 57 | [string] 58 | $ExportFormat, 59 | [Parameter(ParameterSetName = 'Export', 60 | Mandatory = $true)] 61 | [ValidateNotNullOrEmpty()] 62 | [string] 63 | $ExportPath, 64 | [Parameter(ParameterSetName = 'Export')] 65 | [switch] 66 | $NoBinaryData 67 | ) 68 | 69 | begin 70 | { 71 | # Initialize results array 72 | [System.Collections.ArrayList]$returnData = @() 73 | } 74 | 75 | process 76 | { 77 | # Go through all paths 78 | foreach ($path in $KeyPath) 79 | { 80 | if ((Test-IsRegistryKey -KeyPath $path) -eq $true) 81 | { 82 | Write-Verbose "Getting properties for key: $path" 83 | 84 | # Get registry item 85 | $paramGetItem = @{ 86 | Path = $path 87 | ErrorAction = 'Stop' 88 | } 89 | 90 | [Microsoft.Win32.RegistryKey]$regItem = Get-Item @paramGetItem 91 | 92 | # Get key properties 93 | [array]$regItemProperties = $regItem.'Property' 94 | 95 | if ($regItemProperties.Count -gt 0) 96 | { 97 | # Enumerate properties 98 | foreach ($property in $regItemProperties) 99 | { 100 | Write-Verbose "Exporting $property" 101 | 102 | # Append data to return array 103 | [void]($returnData.Add([pscustomobject]@{ 104 | 'Path' = $regItem 105 | 'Name' = $property 106 | 'Value' = $regItem.GetValue($property, $null, 'DoNotExpandEnvironmentNames') 107 | 'Type' = $regItem.GetValueKind($property) 108 | 'Computername' = $env:computername 109 | })) 110 | } 111 | } 112 | else 113 | { 114 | # Return default object 115 | [void]($returnData.Add([pscustomobject]@{ 116 | 'Path' = $regItem 117 | 'Name' = '(Default)' 118 | 'Value' = $null 119 | 'Type' = 'String' 120 | 'Computername' = $env:computername 121 | })) 122 | } 123 | } 124 | else 125 | { 126 | Write-Warning -Message "Key $path does not exist" 127 | 128 | continue 129 | } 130 | } 131 | } 132 | 133 | end 134 | { 135 | # Check we have results 136 | if ($null -ne $returnData) 137 | { 138 | switch ($PSCmdlet.ParameterSetName) 139 | { 140 | 'Export' 141 | { 142 | # Remove binary data 143 | if ($PSBoundParameters.ContainsKey('NoBinaryData')) 144 | { 145 | Write-Verbose -Message 'Removing binary data from return values' 146 | 147 | # Remove binary data 148 | $returnData = $returnData | Where-Object { $_.Type -ne 'Binary' } 149 | } 150 | 151 | switch ($ExportFormat) 152 | { 153 | 'csv' 154 | { 155 | # Export to CSV 156 | $returnData | Export-Csv -Path $ExportPath -NoTypeInformation -Force 157 | } 158 | 'xml' 159 | { 160 | # Export to XML and overwrite 161 | $returnData | Export-Clixml -Path $ExportPath -Force 162 | } 163 | } 164 | 165 | Write-Verbose -Message "Data written to $ExportPath" 166 | } 167 | 168 | default 169 | { 170 | Write-Verbose -Message 'No data will be exported' 171 | 172 | # Print on screen only 173 | $returnData 174 | } 175 | } 176 | } 177 | else 178 | { 179 | Write-Warning -Message 'No found - No export will be created' 180 | } 181 | } 182 | } -------------------------------------------------------------------------------- /Get-ElapsedTime.ps1: -------------------------------------------------------------------------------- 1 | function Get-ElapsedTime 2 | { 3 | <# 4 | .SYNOPSIS 5 | Will return information about elapsed time for the given StopWatch. 6 | 7 | .DESCRIPTION 8 | Function requires a [System.Diagnostics.Stopwatch] object as input and will output information about elapsed time. 9 | 10 | By default a [TimeSpan] object is returned containing all information about elapsed time. 11 | 12 | If any other parameter like -Days is used function will return an Int or Double instead depending on the switch used. 13 | 14 | .PARAMETER ElapsedTime 15 | Will return a [TimeSpan] object representing the elapsed time for the given stopwatch. 16 | 17 | .PARAMETER Days 18 | Will return an [Int] object representing the number of days since the stopwatch was started. 19 | 20 | .PARAMETER Hours 21 | Will return an [Int] object representing the number of hours since the stopwatch was started. 22 | 23 | .PARAMETER Minutes 24 | Will return an [Int] object representing the number of minutes since the stopwatch was started. 25 | 26 | .PARAMETER Seconds 27 | Will return an [Int] object representing the number of seconds since the stopwatch was started. 28 | 29 | .PARAMETER TotalDays 30 | Will return a [Double] object representing the number of TotalDays since the stopwatch was started. 31 | 32 | .PARAMETER TotalHours 33 | Will return a [Double] object representing the number of TotalHours since the stopwatch was started. 34 | 35 | .PARAMETER TotalMinutes 36 | Will return a [Double] object representing the number of TotalMinutes since the stopwatch was started. 37 | 38 | .PARAMETER TotalSeconds 39 | Will return a [Double] object representing the number of TotalSeconds since the stopwatch was started. 40 | 41 | .PARAMETER TotalMilliseconds 42 | Will return a [Double] object representing the number of TotalMilliseconds since the stopwatch was started. 43 | 44 | .EXAMPLE 45 | PS C:\> Get-ElapsedTime -ElapsedTime $ElapsedTime -Days 46 | 47 | .OUTPUTS 48 | System.TimeSpan, System.Double, System.Int32 49 | #> 50 | 51 | [CmdletBinding(DefaultParameterSetName = 'FullOutput', 52 | ConfirmImpact = 'High', 53 | SupportsPaging = $false, 54 | SupportsShouldProcess = $false)] 55 | [OutputType([timespan], ParameterSetName = 'FullOutput')] 56 | [OutputType([int], ParameterSetName = 'Days')] 57 | [OutputType([int], ParameterSetName = 'Hours')] 58 | [OutputType([int], ParameterSetName = 'Minutes')] 59 | [OutputType([int], ParameterSetName = 'Seconds')] 60 | [OutputType([double], ParameterSetName = 'TotalDays')] 61 | [OutputType([double], ParameterSetName = 'TotalHours')] 62 | [OutputType([double], ParameterSetName = 'TotalMinutes')] 63 | [OutputType([double], ParameterSetName = 'TotalSeconds')] 64 | [OutputType([double], ParameterSetName = 'TotalMilliseconds')] 65 | [OutputType([timespan])] 66 | param 67 | ( 68 | [Parameter(ParameterSetName = 'FullOutput', 69 | Mandatory = $true)] 70 | [Parameter(ParameterSetName = 'Days')] 71 | [Parameter(ParameterSetName = 'Hours')] 72 | [Parameter(ParameterSetName = 'Minutes')] 73 | [Parameter(ParameterSetName = 'Seconds')] 74 | [Parameter(ParameterSetName = 'TotalDays')] 75 | [Parameter(ParameterSetName = 'TotalHours')] 76 | [Parameter(ParameterSetName = 'TotalMilliseconds')] 77 | [Parameter(ParameterSetName = 'TotalMinutes')] 78 | [Parameter(ParameterSetName = 'TotalSeconds')] 79 | [System.Diagnostics.Stopwatch] 80 | $ElapsedTime, 81 | [Parameter(ParameterSetName = 'Days')] 82 | [switch] 83 | $Days, 84 | [Parameter(ParameterSetName = 'Hours')] 85 | [switch] 86 | $Hours, 87 | [Parameter(ParameterSetName = 'Minutes')] 88 | [switch] 89 | $Minutes, 90 | [Parameter(ParameterSetName = 'Seconds')] 91 | [switch] 92 | $Seconds, 93 | [Parameter(ParameterSetName = 'TotalDays')] 94 | [switch] 95 | $TotalDays, 96 | [Parameter(ParameterSetName = 'TotalHours')] 97 | [switch] 98 | $TotalHours, 99 | [Parameter(ParameterSetName = 'TotalMinutes')] 100 | [switch] 101 | $TotalMinutes, 102 | [Parameter(ParameterSetName = 'TotalSeconds')] 103 | [switch] 104 | $TotalSeconds, 105 | [Parameter(ParameterSetName = 'TotalMilliseconds')] 106 | [switch] 107 | $TotalMilliseconds 108 | ) 109 | 110 | switch ($PsCmdlet.ParameterSetName) 111 | { 112 | 'FullOutput' 113 | { 114 | # Return full timespan object 115 | return $ElapsedTime.Elapsed 116 | 117 | break 118 | } 119 | 'Days' 120 | { 121 | # Return days with no decimals 122 | return $ElapsedTime.Elapsed.Days 123 | 124 | break 125 | } 126 | 'Hours' 127 | { 128 | # Return hours with no decimals 129 | return $ElapsedTime.Elapsed.Hours 130 | 131 | break 132 | } 133 | 'Minutes' 134 | { 135 | # Return minutes with no decimals 136 | return $ElapsedTime.Elapsed.Minutes 137 | 138 | break 139 | } 140 | 'Seconds' 141 | { 142 | # Return seconds with no decimals 143 | return $ElapsedTime.Elapsed.Seconds 144 | 145 | break 146 | } 147 | 'TotalDays' 148 | { 149 | # Return days with double precision 150 | return $ElapsedTime.Elapsed.TotalDays 151 | 152 | break 153 | } 154 | 'TotalHours' 155 | { 156 | # Return hours with double precision 157 | return $ElapsedTime.Elapsed.TotalHours 158 | 159 | break 160 | } 161 | 'TotalMinutes' 162 | { 163 | # Return minutes with double precision 164 | return $ElapsedTime.Elapsed.TotalMinutes 165 | 166 | break 167 | } 168 | 'TotalSeconds' 169 | { 170 | # Return seconds with double precision 171 | return $ElapsedTime.Elapsed.TotalSeconds 172 | 173 | break 174 | } 175 | 'TotalMilliseconds' 176 | { 177 | # Return milliseconds with double precision 178 | return $ElapsedTime.Elapsed.TotalMilliseconds 179 | 180 | break 181 | } 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /Get-TimerStatus.ps1: -------------------------------------------------------------------------------- 1 | function Get-TimerStatus 2 | { 3 | <# 4 | .SYNOPSIS 5 | Will return boolean value representing status of an existing stopwatch. 6 | 7 | .DESCRIPTION 8 | Function requires a [System.Diagnostics.Stopwatch] object as input and will return $True if stopwatch is running or $False otherwise. 9 | 10 | .PARAMETER Timer 11 | A [System.Diagnostics.Stopwatch] object representing the StopWatch to check status for. 12 | 13 | .EXAMPLE 14 | PS C:\> Get-TimerStatus -Timer $Timer 15 | 16 | .OUTPUTS 17 | System.Boolean 18 | #> 19 | 20 | [OutputType([bool])] 21 | param 22 | ( 23 | [Parameter(Mandatory = $true)] 24 | [System.Diagnostics.Stopwatch] 25 | $Timer 26 | ) 27 | 28 | return $Timer.IsRunning 29 | } -------------------------------------------------------------------------------- /Get-UniqueUPN.ps1: -------------------------------------------------------------------------------- 1 | function Get-UniqueUPN 2 | { 3 | <# 4 | .SYNOPSIS 5 | Cmdlet will generate a forest wide unique UPN. 6 | 7 | .DESCRIPTION 8 | Cmdlet will generate a forest wide unique UPN according to generation rules 9 | defined by the user. 10 | 11 | Cmdlet accept different types of objects to generate the UPN to allow greater flexibility 12 | 13 | ADObject - For example and object from Get-AdUser cmdlet 14 | Strings - Representing First Name, Last Name etc. 15 | DirectoryService Objects - For example when using native .Net methods to retrieve the identity 16 | 17 | .PARAMETER ADObject 18 | An ADObject for example output of the Get-ADUser cmdlet 19 | 20 | .PARAMETER FirstName 21 | A string representing the First Name of the user 22 | 23 | .PARAMETER LastName 24 | A string representing the Last Name of the user 25 | 26 | .PARAMETER MiddleName 27 | A string representing the Middle Name of the user, parameter is optional. 28 | 29 | .PARAMETER UPNSuffix 30 | A string representing the UPN suffix to be used. 31 | 32 | .PARAMETER FirstNameFormat 33 | A string representing the format to be for the First Name part of the UPN. 34 | 35 | .PARAMETER LastNameFormat 36 | A string representing the format to be for the Last Name part of the UPN. 37 | 38 | .PARAMETER IncludeMiddleName 39 | When paramenter is specified user Middle Name, if present, will be included in the UPN generation process. 40 | 41 | .PARAMETER ADServer 42 | A string representing the name of the AD Domain Controller that will be used to query Active Directory. 43 | 44 | If no server is specified the closest Global Catalog will be automatically selected. 45 | 46 | .PARAMETER Separator 47 | A string representing the separator to be used between UPN parts, defaults to a '.'. 48 | #> 49 | 50 | [CmdletBinding(DefaultParameterSetName = 'Strings')] 51 | param 52 | ( 53 | [Parameter(ParameterSetName = 'ADObject', 54 | Mandatory = $true)] 55 | [object]$ADObject, 56 | [Parameter(ParameterSetName = 'Strings', 57 | Mandatory = $true)] 58 | [ValidateNotNullOrEmpty()] 59 | [string]$FirstName, 60 | [Parameter(ParameterSetName = 'Strings', 61 | Mandatory = $true)] 62 | [ValidateNotNullOrEmpty()] 63 | [string]$LastName, 64 | [Parameter(ParameterSetName = 'Strings')] 65 | [ValidateNotNullOrEmpty()] 66 | [string]$MiddleName, 67 | [Parameter(Mandatory = $true)] 68 | [ValidateNotNullOrEmpty()] 69 | [string]$UPNSuffix, 70 | [ValidateSet('FullName', 'FirstLetter', IgnoreCase = $true)] 71 | [ValidateNotNullOrEmpty()] 72 | [string]$FirstNameFormat = 'Full', 73 | [ValidateSet('FullName', 'FirstLetter', IgnoreCase = $true)] 74 | [ValidateNotNullOrEmpty()] 75 | [string]$LastNameFormat = 'FullName', 76 | [switch]$IncludeMiddleName, 77 | [ValidateNotNullOrEmpty()] 78 | [string]$ADServer, 79 | [ValidateNotNullOrEmpty()] 80 | [string]$Separator = '.' 81 | ) 82 | 83 | if ($PSCmdlet.ParameterSetName -eq 'ADObject') 84 | { 85 | switch ($ADObject.GetType().FullName) 86 | { 87 | 'Microsoft.ActiveDirectory.Management.ADUser' 88 | { 89 | [string]$firstName = $ADObject.GivenName 90 | [string]$lastName = $ADObject.Surname 91 | [string]$middleName = $ADObject.MiddleName 92 | 93 | break 94 | } 95 | 'System.DirectoryServices.DirectoryEntry' 96 | { 97 | [string]$firstName = $ADObject.Properties['givenName'][0] 98 | [string]$lastName = $ADObject.Properties['sn'][0] 99 | [string]$middleName = $ADObject.Properties['middleName'][0] 100 | 101 | break 102 | } 103 | 'System.DirectoryServices.SearchResult' 104 | { 105 | [string]$firstName = $ADObject.Properties['givenName'][0] 106 | [string]$lastName = $ADObject.Properties['sn'][0] 107 | [string]$middleName = $ADObject.Properties['middleName'][0] 108 | 109 | break 110 | } 111 | default 112 | { 113 | throw "Unsupported AD object type: $($ADObject.GetType().FullName)" 114 | } 115 | } 116 | } 117 | else 118 | { 119 | [string]$firstName = $FirstName 120 | [string]$lastName = $LastName 121 | [string]$middleName = $MiddleName 122 | } 123 | 124 | # Format first name 125 | $firstName = switch ($FirstNameFormat) 126 | { 127 | 'FullName' 128 | { 129 | $firstName 130 | } 131 | 'FirstLetter' 132 | { 133 | $firstName.Substring(0, 1) 134 | } 135 | } 136 | 137 | # Format last name 138 | $LastName = switch ($FirstNameFormat) 139 | { 140 | 'FullName' 141 | { 142 | $LastName 143 | } 144 | 'FirstLetter' 145 | { 146 | $LastName.Substring(0, 1) 147 | } 148 | } 149 | 150 | # Use middle name 151 | [string]$middleNamePart = if ($IncludeMiddleName -and $MiddleName) 152 | { 153 | '{0}{1}' -f $Separator, $MiddleName 154 | } 155 | 156 | # Setup required attributes 157 | [string]$baseUPN = ('{0}{1}{2}{3}@{4}' -f $FirstName, $middleNamePart, $Separator, $LastName, $UPNSuffix).ToLower() 158 | [string]$uniqueUPN = $baseUPN 159 | [int]$counter = 1 160 | 161 | while (Test-UPNExist -UPN $uniqueUPN -Server $ADServer) 162 | { 163 | $uniqueUPN = '{0}{1}@{2}' -f ($baseUPN.Split('@')[0]), $counter, $UPNSuffix 164 | 165 | $counter++ 166 | } 167 | 168 | return $uniqueUPN 169 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Daniele Catanesi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /New-ApiRequest.ps1: -------------------------------------------------------------------------------- 1 | function New-ApiRequest 2 | { 3 | <# 4 | .SYNOPSIS 5 | Function will query data from an URL API. 6 | 7 | .DESCRIPTION 8 | Function is intended as a wrapper around PowerShell built-in Invoke-RestMethod cmdlet allowing user to quickly generate web requests to APIs requiring OAuth2 authentication. 9 | 10 | .PARAMETER ApiKey 11 | A string representing the API key to be used. 12 | 13 | .PARAMETER ApiSecret 14 | A string representing the API key secret. 15 | 16 | .PARAMETER ApiUrl 17 | A string representing the API endpoint URL 18 | 19 | .PARAMETER GrantType 20 | A string representing the Grant Type supported by the API. 21 | 22 | If not specified it will default to client_credentials. 23 | 24 | .PARAMETER ContentType 25 | A string representing the content type to send as part of the request in case request needs to be crafted with a special ContentType. 26 | 27 | .PARAMETER Method 28 | A string representing the method to be used in the web request. 29 | 30 | If not specified it will default to GET. 31 | 32 | .PARAMETER Headers 33 | A string representing custom headers to send as part of the webrequest. 34 | 35 | .EXAMPLE 36 | PS C:\> New-ApiRequest -ApiKey 'Value1' -ApiUrl 'Value2' -ApiSecret 'MySecret' 37 | 38 | .NOTES 39 | Additional information about the function. 40 | #> 41 | 42 | [CmdletBinding()] 43 | [OutputType([pscustomobject])] 44 | param 45 | ( 46 | [Parameter(Mandatory = $true)] 47 | [string] 48 | $ApiKey, 49 | [string] 50 | $ApiSecret, 51 | [Parameter(Mandatory = $true)] 52 | [ValidateNotNullOrEmpty()] 53 | [string] 54 | $ApiUrl, 55 | [ValidateNotNullOrEmpty()] 56 | [string] 57 | $GrantType = 'client_credentials', 58 | [ValidateNotNullOrEmpty()] 59 | [string] 60 | $ContentType, 61 | [ValidateNotNullOrEmpty()] 62 | [ValidateSet('GET', 'POST', IgnoreCase = $true)] 63 | [string] 64 | $Method = 'GET', 65 | [ValidateNotNullOrEmpty()] 66 | [string] 67 | $Headers 68 | ) 69 | 70 | Process 71 | { 72 | # Generate request post data 73 | [hashtable]$requestBody = @{ 74 | 'client_id' = $ApiKey; 75 | 'grant_type' = $GrantType 76 | } 77 | 78 | switch ($PSBoundParameters.Keys) 79 | { 80 | 'ContentType' 81 | { 82 | $requestBody.Add('ContentType', $ContentType) 83 | 84 | break 85 | } 86 | 'ApiSecret' 87 | { 88 | $requestBody.Add('client_secret', $ApiSecret) 89 | 90 | break 91 | } 92 | } 93 | 94 | # Define splat command 95 | $paramInvokeWebRequest = @{ 96 | Uri = $ApiUrl 97 | Body = $requestBody 98 | } 99 | 100 | # Get passed parameters 101 | switch ($PSBoundParameters.Keys) 102 | { 103 | 'Headers' 104 | { 105 | # Add custom header 106 | $paramInvokeWebRequest.Add('Headers', $Headers) 107 | 108 | break 109 | } 110 | 'Method' 111 | { 112 | # Use custom method 113 | $paramInvokeWebRequest.Add('Method', $Method) 114 | 115 | break 116 | } 117 | } 118 | 119 | return Invoke-RestMethod @paramInvokeWebRequest 120 | } 121 | } -------------------------------------------------------------------------------- /New-StringConversion.ps1: -------------------------------------------------------------------------------- 1 | function New-StringConversion 2 | { 3 | <# 4 | .SYNOPSIS 5 | Function to remove any non-unicode character from a string. 6 | 7 | .DESCRIPTION 8 | Function is used to sanitize non-unicode characters from a string. 9 | 10 | Function supports custom characters map via the -UnicodeHashTable parameter accepting an hashtable of characters to replace. 11 | 12 | If characters not specified in the default character map are found they are replace with a question mark '?' unless a custom 13 | unknown character is specified via -UnknownCharacter parameter. 14 | 15 | .PARAMETER StringToConvert 16 | A string containing characters that need to be sanitized/converted. 17 | 18 | .PARAMETER UnicodeHashTable 19 | An hashtable containing characters that should be replaced if parameter is not specified default values will be used. 20 | 21 | .PARAMETER IgnoreSpaces 22 | By default spaces will be replaced with a dash '-' sign if paramter is specified function will not convert/take into consideraiotn 23 | spaces in the string. 24 | 25 | .PARAMETER RemoveSpaces 26 | If parameter is specified spaces will be removed from input string. 27 | 28 | .PARAMETER ReplaceSpaces 29 | By default spaces will be replaced with a dash '-' sign if parameter is specified it is possible to specify character to use when 30 | a space is encountered in the string. 31 | 32 | .PARAMETER UnknownCharacter 33 | By default any special character not found in the UnicodeHashTable will be replaced with a question mark when parameter is used 34 | it is possible to specify which character will be used for unknown entries. 35 | 36 | .EXAMPLE 37 | PS C:\> New-StringConversion 38 | 39 | .NOTES 40 | Additional information about the function. 41 | #> 42 | [CmdletBinding(DefaultParameterSetName = 'ReplaceSpaces', 43 | ConfirmImpact = 'High', 44 | HelpUri = 'https://PsCustomObject.github.io')] 45 | param 46 | ( 47 | [Parameter(ParameterSetName = 'IgnoreSpaces', 48 | Mandatory = $true)] 49 | [Parameter(ParameterSetName = 'RemoveSpaces')] 50 | [Parameter(ParameterSetName = 'ReplaceSpaces')] 51 | [ValidateNotNullOrEmpty()] 52 | [string] 53 | $StringToConvert, 54 | [Parameter(ParameterSetName = 'IgnoreSpaces')] 55 | [Parameter(ParameterSetName = 'RemoveSpaces')] 56 | [Parameter(ParameterSetName = 'ReplaceSpaces')] 57 | [hashtable] 58 | $UnicodeHashTable, 59 | [Parameter(ParameterSetName = 'IgnoreSpaces')] 60 | [switch] 61 | $IgnoreSpaces, 62 | [Parameter(ParameterSetName = 'RemoveSpaces')] 63 | [switch] 64 | $RemoveSpaces, 65 | [Parameter(ParameterSetName = 'ReplaceSpaces')] 66 | [ValidateNotNullOrEmpty()] 67 | [string] 68 | $ReplaceSpaces, 69 | [Parameter(ParameterSetName = 'IgnoreSpaces')] 70 | [Parameter(ParameterSetName = 'RemoveSpaces')] 71 | [Parameter(ParameterSetName = 'ReplaceSpaces')] 72 | [ValidateNotNullOrEmpty()] 73 | [string] 74 | $UnknownCharacter = '?' 75 | ) 76 | 77 | begin 78 | { 79 | # Declare control variable 80 | [bool]$isUpperCase = $false 81 | 82 | # Check if we should use custom array hash 83 | if (-not ($PSBoundParameters.ContainsKey('UnicodeHashTable'))) 84 | { 85 | # Hashtable contaning special characters to replace 86 | [hashtable]$unicodeHashTable = @{ 87 | 88 | # a 89 | 'æ' = 'a' 90 | 'à' = 'a' 91 | 'â' = 'a' 92 | 'ã' = 'a' 93 | 'å' = 'a' 94 | 'ā' = 'a' 95 | 'ă' = 'a' 96 | 'ą' = 'a' 97 | 'ä' = 'a' 98 | 'á' = 'a' 99 | 100 | # b 101 | 'ƀ' = 'b' 102 | 'ƃ' = 'b' 103 | 104 | # Tone six 105 | 'ƅ' = 'b' 106 | 107 | # c 108 | 'ç' = 'c' 109 | 'ć' = 'c' 110 | 'ĉ' = 'c' 111 | 'ċ' = 'c' 112 | 'č' = 'c' 113 | 'ƈ' = 'c' 114 | 115 | # d 116 | 'ď' = 'd' 117 | 'đ' = 'd' 118 | 'ƌ' = 'd' 119 | 120 | # e 121 | 'è' = 'e' 122 | 'é' = 'e' 123 | 'ê' = 'e' 124 | 'ë' = 'e' 125 | 'ē' = 'e' 126 | 'ĕ' = 'e' 127 | 'ė' = 'e' 128 | 'ę' = 'e' 129 | 'ě' = 'e' 130 | '&' = 'e' 131 | 132 | # g 133 | 'ĝ' = 'e' 134 | 'ğ' = 'e' 135 | 'ġ' = 'e' 136 | 'ģ' = 'e' 137 | 138 | # h 139 | 'ĥ' = 'h' 140 | 'ħ' = 'h' 141 | 142 | # i 143 | 'ì' = 'i' 144 | 'í' = 'i' 145 | 'î' = 'i' 146 | 'ï' = 'i' 147 | 'ĩ' = 'i' 148 | 'ī' = 'i' 149 | 'ĭ' = 'i' 150 | 'į' = 'i' 151 | 'ı' = 'i' 152 | 153 | # j 154 | 'ij' = 'j' 155 | 'ĵ' = 'j' 156 | 157 | # k 158 | 'ķ' = 'k' 159 | 'ĸ' = 'k' 160 | 161 | # l 162 | 'ĺ' = 'l' 163 | 'ļ' = 'l' 164 | 'ľ' = 'l' 165 | 'ŀ' = 'l' 166 | 'ł' = 'l' 167 | 168 | # n 169 | 'ñ' = 'n' 170 | 'ń' = 'n' 171 | 'ņ' = 'n' 172 | 'ň' = 'n' 173 | 'ʼn' = 'n' 174 | 'ŋ' = 'n' 175 | 176 | # o 177 | 'ð' = 'o' 178 | 'ó' = 'o' 179 | 'õ' = 'o' 180 | 'ô' = 'o' 181 | 'ö' = 'o' 182 | 'ø' = 'o' 183 | 'ō' = 'o' 184 | 'ŏ' = 'o' 185 | 'ő' = 'o' 186 | 'œ' = 'o' 187 | 188 | # r 189 | 'ŕ' = 'r' 190 | 'ŗ' = 'r' 191 | 'ř' = 'r' 192 | 193 | # s 194 | 'ś' = 's' 195 | 'ŝ' = 's' 196 | 'ş' = 's' 197 | 'š' = 's' 198 | 'ß' = 'ss' 199 | 'ſ' = 's' 200 | 201 | # t 202 | 'ţ' = 't' 203 | 'ť' = 't' 204 | 'ŧ' = 't' 205 | 206 | # u 207 | 'ù' = 'u' 208 | 'ú' = 'u' 209 | 'û' = 'u' 210 | 'ü' = 'u' 211 | 'ũ' = 'u' 212 | 'ū' = 'u' 213 | 'ŭ' = 'u' 214 | 'ů' = 'u' 215 | 'ű' = 'u' 216 | 'ų' = 'u' 217 | 218 | # w 219 | 'ŵ' = 'w' 220 | 221 | # y 222 | 'ý' = 'y' 223 | 'ÿ' = 'y' 224 | 'ŷ' = 'y' 225 | 226 | # z 227 | 'ź' = 'z' 228 | 'ż' = 'z' 229 | 'ž' = 'z' 230 | } 231 | } 232 | 233 | switch ($PSBoundParameters.Keys) 234 | { 235 | 'IgnoreSpaces' 236 | { 237 | $UnicodeHashTable.Add(' ', ' ') 238 | 239 | break 240 | } 241 | 'ReplaceSpaces' 242 | { 243 | # Replace spaces with specified character 244 | $UnicodeHashTable.Add(' ', $ReplaceSpaces) 245 | 246 | break 247 | } 248 | 'RemoveSpaces' 249 | { 250 | # Replace spaces with specified character 251 | $UnicodeHashTable.Add(' ', '') 252 | 253 | break 254 | } 255 | } 256 | 257 | # Create new chararray 258 | [System.Collections.ArrayList]$resultStringArray = @() 259 | 260 | # Set a regex for additional special characters 261 | [string]$unicodeRegExString = "^([0-9a-zA-Z!#$@.'^_`~-])*$" 262 | } 263 | process 264 | { 265 | # Convert string to array 266 | [array]$stringCharArray = $StringToConvert.ToCharArray() 267 | 268 | foreach ($character in $stringCharArray) 269 | { 270 | # Reset control variables 271 | $isUpperCase = $false 272 | 273 | # Set Char ref with current value 274 | [string]$currentChar = $character.ToString() 275 | [string]$currentCharLower = $character.ToString().ToLower() 276 | 277 | # Get character case 278 | if ($currentChar.CompareTo($currentCharLower) -eq 1) 279 | { 280 | $isUpperCase = $true 281 | } 282 | 283 | # Check if character should be translated 284 | if ($UnicodeHashTable.ContainsKey($currentCharLower) -eq $true) 285 | { 286 | # Get unicode equivalent 287 | [string]$tmpChar = $UnicodeHashTable[$currentChar] 288 | 289 | # Set character case 290 | switch ($isUpperCase) 291 | { 292 | $true 293 | { 294 | $resultStringArray.Add($tmpChar.ToUpper()) 295 | 296 | break 297 | } 298 | default 299 | { 300 | $resultStringArray.Add($tmpChar) 301 | } 302 | } 303 | } 304 | else 305 | { 306 | # Check if character should be translated 307 | if (($currentCharLower -match $unicodeRegExString) -eq $false) 308 | { 309 | # Handle characters not in hash 310 | $currentChar = $UnknownCharacter 311 | 312 | # Append to result array 313 | $resultStringArray.Add($currentChar).ToString() 314 | } 315 | else 316 | { 317 | # Set character case 318 | switch ($isUpperCase) 319 | { 320 | $true 321 | { 322 | $resultStringArray.Add($currentChar).ToString().ToUpper() 323 | } 324 | default 325 | { 326 | $resultStringArray.Add($currentChar).ToString() 327 | } 328 | } 329 | } 330 | } 331 | } 332 | } 333 | end 334 | { 335 | # Return string 336 | return (-join $resultStringArray) 337 | } 338 | } -------------------------------------------------------------------------------- /New-Timer.ps1: -------------------------------------------------------------------------------- 1 | function New-Timer 2 | { 3 | <# 4 | .SYNOPSIS 5 | Creates a new stopwatch. 6 | 7 | .DESCRIPTION 8 | Function will create a new time, using the StopWatch class, allowing measurement of elapsed time in scripts. 9 | 10 | .EXAMPLE 11 | PS C:\> New-Timer 12 | 13 | .NOTES 14 | Function takes no parameters and will start a new StopWatch object. 15 | #> 16 | 17 | [OutputType([System.Diagnostics.Stopwatch])] 18 | param () 19 | 20 | $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() 21 | 22 | return $stopwatch 23 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PowerShell-Functions 2 | 3 | Repository is used to store and shared useful PowerShell functions that have been developed to serve a specific purpose. 4 | 5 | Functions in the repository are usually ported into my PowerShell modules but are also made available as *single* files for easier download in case the whole module is not needed. 6 | 7 | ## Current available functions 8 | 9 | - **[New-Timer](https://github.com/PsCustomObject/PowerShell-Functions/blob/master/New-Timer.ps1)** used to instantiate and start a new StopWatch timer object 10 | 11 | - **[Get-ElapsedTime](https://github.com/PsCustomObject/PowerShell-Functions/blob/master/Get-ElapsedTime.ps1)** used to return information about a StopWatch timer object 12 | 13 | - **[Stop-Timer](https://github.com/PsCustomObject/PowerShell-Functions/blob/master/Stop-Timer.ps1)** used to halt and existing StopWatch timer object 14 | 15 | - **[Get-TimerStatus](https://github.com/PsCustomObject/PowerShell-Functions/blob/master/Get-TimerStatus.ps1)** used to get status of an existing StopWatch timer object 16 | 17 | - **[New-ApiRequest](https://github.com/PsCustomObject/PowerShell-Functions/blob/master/New-ApiRequest.ps1)** used to quickly generate API calls to services supporting OAuth2 authentication 18 | 19 | - **[Test-IsGuid](https://github.com/PsCustomObject/PowerShell-Functions/blob/master/Test-IsGuid.ps1)** used to check if a string is a valid GUID 20 | 21 | - **[Convert-EmlFile](https://github.com/PsCustomObject/PowerShell-Functions/blob/master/Convert-EmlFile.ps1)** used to convert any eml file into an easy to use PowerShell object 22 | 23 | - **[New-StringConversion](https://github.com/PsCustomObject/PowerShell-Functions/blob/master/New-StringConversion.ps1)** used to convert special characters from strings 24 | 25 | - **[Test-IsRegistryKey](https://github.com/PsCustomObject/PowerShell-Functions/blob/master/Test-IsRegistryKey.ps1)** used to check if a registry key is valid. Function is a helper for *[Export-Registry](https://github.com/PsCustomObject/PowerShell-Functions/blob/master/Export-Registry.ps1)* 26 | 27 | - **[Export-Registry](https://github.com/PsCustomObject/PowerShell-Functions/blob/master/Export-Registry.ps1)** used to export registry key in either *CSV* or *XML* format 28 | 29 | - **[Test-IsValidDN](https://github.com/PsCustomObject/PowerShell-Functions/Test-IsValidDn.ps1)** used to test if an input string is a valid **AD Distinguished Name** -------------------------------------------------------------------------------- /Stop-Timer.ps1: -------------------------------------------------------------------------------- 1 | function Stop-Timer 2 | { 3 | <# 4 | .SYNOPSIS 5 | Function will halt a stopwatch. 6 | 7 | .DESCRIPTION 8 | Function requires a [System.Diagnostics.Stopwatch] object as input and will invoke the stop() method to hald its execution. 9 | 10 | If no exceptions are returned function will return $True. 11 | 12 | .PARAMETER Timer 13 | A [System.Diagnostics.Stopwatch] representing the stopwatch to stop. 14 | 15 | .EXAMPLE 16 | PS C:\> Stop-Timer -Timer $Timer 17 | 18 | .OUTPUTS 19 | System.Boolean 20 | #> 21 | 22 | [OutputType([bool])] 23 | param 24 | ( 25 | [Parameter(Mandatory = $true)] 26 | [System.Diagnostics.Stopwatch]$Timer 27 | ) 28 | 29 | Begin 30 | { 31 | # Save current configuration 32 | [string]$currentConfig = $ErrorActionPreference 33 | 34 | # Update configuration 35 | $ErrorActionPreference = 'Stop' 36 | } 37 | 38 | Process 39 | { 40 | try 41 | { 42 | # Stop timer 43 | $Timer.Stop() 44 | 45 | return $true 46 | } 47 | catch 48 | { 49 | # Save exception 50 | [string]$reportedException = $Error[0].Exception.Message 51 | 52 | Write-Warning -Message 'Exception reported while halting stopwatch - Use the -Verbose parameter for more details' 53 | 54 | # Check we have an exception message 55 | if ([string]::IsNullOrEmpty($reportedException) -eq $false) 56 | { 57 | Write-Verbose -Message $reportedException 58 | } 59 | else 60 | { 61 | Write-Verbose -Message 'No inner exception reported by Disconnect-AzureAD cmdlet' 62 | } 63 | 64 | return $false 65 | } 66 | } 67 | 68 | End 69 | { 70 | # Revert back configuration 71 | $ErrorActionPreference = $currentConfig 72 | } 73 | } -------------------------------------------------------------------------------- /Test-IsEmail.ps1: -------------------------------------------------------------------------------- 1 | function Test-IsEmail 2 | { 3 | <# 4 | .SYNOPSIS 5 | Function to check if a string is an RFC email address. 6 | 7 | .DESCRIPTION 8 | Function will check if an input string is an RFC complient email address. 9 | 10 | .PARAMETER EmailAddress 11 | A string representing the email address to be checked 12 | 13 | .EXAMPLE 14 | PS C:\> Test-IsEmail -EmailAddress 'value1' 15 | 16 | .OUTPUTS 17 | System.Boolean 18 | 19 | .LINK 20 | Restrictions on email addresses 21 | https://tools.ietf.org/html/rfc3696#section-3 22 | #> 23 | 24 | [OutputType([bool])] 25 | param 26 | ( 27 | [Parameter(Mandatory = $true)] 28 | [ValidateNotNullOrEmpty()] 29 | [Alias('Email', 'Mail', 'Address')] 30 | [string] 31 | $EmailAddress 32 | ) 33 | 34 | try 35 | { 36 | # Check if address is RFC compliant 37 | [void]([mailaddress]$EmailAddress) 38 | 39 | Write-Verbose -Message "Address $EmailAddress is an RFC compliant address" 40 | 41 | return $true 42 | } 43 | catch 44 | { 45 | Write-Verbose -Message "Address $EmailAddress is not an RFC compliant address" 46 | 47 | return $false 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Test-IsGuid.ps1: -------------------------------------------------------------------------------- 1 | function Test-IsGuid 2 | { 3 | <# 4 | .SYNOPSIS 5 | Cmdlet will check if input string is a valid GUID. 6 | 7 | .DESCRIPTION 8 | Cmdlet will check if input string is a valid GUID. 9 | 10 | .PARAMETER ObjectGuid 11 | A string representing the GUID to be tested. 12 | 13 | .EXAMPLE 14 | PS C:\> Test-IsGuid -ObjectGuid 'value1' 15 | 16 | # Output 17 | $False 18 | 19 | .EXAMPLE 20 | PS C:\> Test-IsGuid -ObjectGuid '7761bf39-9a9f-42c8-869f-7c6e2689811a' 21 | 22 | # Output 23 | $True 24 | 25 | .OUTPUTS 26 | System.Boolean 27 | 28 | .NOTES 29 | Additional information about the function. 30 | #> 31 | [OutputType([bool])] 32 | param 33 | ( 34 | [Parameter(Mandatory = $true)] 35 | [string] 36 | $ObjectGuid 37 | ) 38 | 39 | # Define verification regex 40 | [regex]$guidRegex = '(?im)^[{(]?[0-9A-F]{8}[-]?(?:[0-9A-F]{4}[-]?){3}[0-9A-F]{12}[)}]?$' 41 | 42 | # Check guid against regex 43 | return $ObjectGuid -match $guidRegex 44 | } 45 | -------------------------------------------------------------------------------- /Test-IsRegistryKey.ps1: -------------------------------------------------------------------------------- 1 | function Test-IsRegistryKey 2 | { 3 | <# 4 | .SYNOPSIS 5 | Cmdlet will check if the specified registry key is valid. 6 | 7 | .DESCRIPTION 8 | Cmdlet will check if the specified registry path is valid. 9 | 10 | .PARAMETER KeyPath 11 | A string representing the registry path to check in the PSDrive format IE HKLM:\SOFTWARE 12 | 13 | .EXAMPLE 14 | PS C:\> Test-IsRegistryKey -KeyPath 'value1' 15 | #> 16 | 17 | [OutputType([bool])] 18 | param 19 | ( 20 | [Parameter(Mandatory = $true)] 21 | [ValidateNotNullOrEmpty()] 22 | [string] 23 | $KeyPath 24 | ) 25 | 26 | if (Test-Path -Path $KeyPath) 27 | { 28 | return (Get-Item -Path $KeyPath).PsProvider.Name -match 'Registry' 29 | } 30 | else 31 | { 32 | return $false 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Test-IsValidDn.ps1: -------------------------------------------------------------------------------- 1 | function Test-IsValidDN 2 | { 3 | <# 4 | .SYNOPSIS 5 | Cmdlet will check if the input string is a valid distinguishedname. 6 | 7 | .DESCRIPTION 8 | Cmdlet will check if the input string is a valid distinguishedname. 9 | 10 | Cmdlet is intended as a dignostic tool for input validation 11 | 12 | .PARAMETER ObjectDN 13 | A string representing the object distinguishedname. 14 | 15 | .EXAMPLE 16 | PS C:\> Test-IsValidDN -ObjectDN 'Value1' 17 | #> 18 | 19 | [OutputType([bool])] 20 | param 21 | ( 22 | [Parameter(Mandatory = $true)] 23 | [ValidateNotNullOrEmpty()] 24 | [Alias('DN', 'DistinguishedName')] 25 | [string] 26 | $ObjectDN 27 | ) 28 | 29 | # Create new string builder 30 | [System.Text.StringBuilder]$regexStringBuilder = [System.Text.StringBuilder]::New() 31 | [void]($regexStringBuilder.Append('^(?:[A-Za-z][\w-]*|\d+(?:\.\d+)*)=(?:#(?:[\dA-Fa-f]{2})+|')) 32 | [void]($regexStringBuilder.Append('(?:[^,=\+<>#;\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*|"(?:')) 33 | [void]($regexStringBuilder.Append('[^\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*")(?:\+(?:[A-Za-z]')) 34 | [void]($regexStringBuilder.Append('[\w-]*|\d+(?:\.\d+)*)=(?:#(?:[\dA-Fa-f]{2})+|(?:[^,=\+<>#;\\"]')) 35 | [void]($regexStringBuilder.Append('|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*|"(?:[^\\"]|\\[,=\+<>#;\\"]|')) 36 | [void]($regexStringBuilder.Append('\\[\dA-Fa-f]{2})*"))*(?:,(?:[A-Za-z][\w-]*|\d+(?:\.\d+)*)=(?:#')) 37 | [void]($regexStringBuilder.Append('(?:[\dA-Fa-f]{2})+|(?:[^,=\+<>#;\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]')) 38 | [void]($regexStringBuilder.Append('{2})*|"(?:[^\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*")(?:\+(?:[A-Za-z]')) 39 | [void]($regexStringBuilder.Append('[\w-]*|\d+(?:\.\d+)*)=(?:#(?:[\dA-Fa-f]{2})+|(?:[^,=\+<>#;\\"]|\\[,=\')) 40 | [void]($regexStringBuilder.Append('+<>#;\\"]|\\[\dA-Fa-f]{2})*|"(?:[^\\"]|\\[,=\+<>#;\\"]|\\[\dA-Fa-f]{2})*"))*)*$')) 41 | 42 | # Define DN Regex 43 | [string]$distinguishedNameRegex = $regexStringBuilder.ToString() 44 | 45 | return $ObjectDN -match $distinguishedNameRegex 46 | } -------------------------------------------------------------------------------- /Test-UpnExist.ps1: -------------------------------------------------------------------------------- 1 | function Test-UPNExist 2 | { 3 | <# 4 | .SYNOPSIS 5 | Cmdlet will check if a given UPN exists in the forest. 6 | 7 | .DESCRIPTION 8 | Cmdlet is a diagnostic tool to check if a given UPN is already assigned to a user in the forest. 9 | 10 | .PARAMETER UPN 11 | A string representing the UPN to check for uniqueness. 12 | 13 | .PARAMETER AdServer 14 | A string representing the name of the domain controller to be used for the check, if parameter 15 | is not specified the closest Global Catalog is used. 16 | 17 | .EXAMPLE 18 | PS C:\> Test-UPNExist -UPN 'John.Doe@example.com' 19 | #> 20 | 21 | [CmdletBinding()] 22 | param 23 | ( 24 | [Parameter(Mandatory = $true)] 25 | [ValidateNotNullOrEmpty()] 26 | [string]$UPN, 27 | [ValidateNotNullOrEmpty()] 28 | [string]$AdServer 29 | ) 30 | 31 | if ([string]::IsNullOrEmpty($AdServer) -eq $true) 32 | { 33 | $adForest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest() 34 | [string]$ldapPath = '{0}{1}' -f 'GC://', $($adForest.FindGlobalCatalog().Name) 35 | } 36 | else 37 | { 38 | [string]$ldapPath = '{0}{1}' -f 'LDAP://', $AdServer 39 | } 40 | 41 | # Instantiate required objects and run query 42 | $adDomain = New-Object System.DirectoryServices.DirectoryEntry($ldapPath) 43 | $adSearcher = New-Object System.DirectoryServices.DirectorySearcher($adDomain) 44 | $adSearcher.SearchScope = 'Subtree' 45 | $adSearcher.PageSize = 1000 46 | $adSearcher.Filter = "(&(objectCategory=person)(userPrincipalName=$UPN))" 47 | [void]($adSearcher.PropertiesToLoad.Add("userPrincipalName")) 48 | 49 | [array]$searchResult = $adSearcher.FindOne() 50 | 51 | return $null -ne $searchResult 52 | } --------------------------------------------------------------------------------