PowerShell to get the CIDR Notation by Subnet Mask

The following function provides an easy way to get the CIDR (Classless Inter Domain Routing) notation for any subnet mask using PowerShell.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# Calculate CIDR (Classless Inter Domain Routing) Notation
function getCIDRNotationBySubnetmask([string]$subnetmask){
 
    $cidr = 0
    $subnetmask.split(".") | foreach {
        switch($_){
            255 { $cidr += 8 }
            254 { $cidr += 7 }
            252 { $cidr += 6 }
            248 { $cidr += 5 }
            240 { $cidr += 4 }
            224 { $cidr += 3 }
            192 { $cidr += 2 }
            128 { $cidr += 1 }
            default { $cidr += 0 }
        }
    }
 
    return $cidr
}
 
# Examples how to use it
getCIDRNotationBySubnetmask 0.0.0.0
 
getCIDRNotationBySubnetmask 128.0.0.0
getCIDRNotationBySubnetmask 192.0.0.0
getCIDRNotationBySubnetmask 224.0.0.0
getCIDRNotationBySubnetmask 240.0.0.0
getCIDRNotationBySubnetmask 248.0.0.0
getCIDRNotationBySubnetmask 252.0.0.0
getCIDRNotationBySubnetmask 254.0.0.0
getCIDRNotationBySubnetmask 255.0.0.0
 
getCIDRNotationBySubnetmask 255.128.0.0
getCIDRNotationBySubnetmask 255.192.0.0
getCIDRNotationBySubnetmask 255.224.0.0
getCIDRNotationBySubnetmask 255.240.0.0
getCIDRNotationBySubnetmask 255.248.0.0
getCIDRNotationBySubnetmask 255.252.0.0
getCIDRNotationBySubnetmask 255.254.0.0
getCIDRNotationBySubnetmask 255.255.0.0
 
getCIDRNotationBySubnetmask 255.255.128.0
getCIDRNotationBySubnetmask 255.255.192.0
getCIDRNotationBySubnetmask 255.255.224.0
getCIDRNotationBySubnetmask 255.255.240.0
getCIDRNotationBySubnetmask 255.255.248.0
getCIDRNotationBySubnetmask 255.255.252.0
getCIDRNotationBySubnetmask 255.255.254.0
getCIDRNotationBySubnetmask 255.255.255.0
 
getCIDRNotationBySubnetmask 255.255.255.128
getCIDRNotationBySubnetmask 255.255.255.192
getCIDRNotationBySubnetmask 255.255.255.224
getCIDRNotationBySubnetmask 255.255.255.240
getCIDRNotationBySubnetmask 255.255.255.248
getCIDRNotationBySubnetmask 255.255.255.252
getCIDRNotationBySubnetmask 255.255.255.254
 
getCIDRNotationBySubnetmask 255.255.255.255

Delegate Permission on Active Directory Organizational Unit using Powershell

In case you need to delegate permissions on an Active Directory (AD) Organizational Unit (OU) for a security principal such as a User or a Group, you can easily do that with the follwing PowerShell function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function Set-Delegation(){
    param(
    [string]$OrganizationalUnit,
    [string]$DelegationGroupName
    )
 
    # Configuration Parameters
    $confADRight = "GenericAll"
    $confDelegatedObjectType = "00000000-0000-0000-0000-000000000000"
 
    # Collect and prepare Objects
    $delegationGroup = Get-ADGroup -Identity $DelegationGroupName
    $delegationGroupSID = [System.Security.Principal.SecurityIdentifier] $delegationGroup.SID
    $delegationGroupACL = Get-Acl -Path "AD:\$OrganizationalUnit"
 
    # Build Access Control Entry (ACE)
    $aceIdentity = [System.Security.Principal.IdentityReference] $delegationGroupSID
    $aceADRight = [System.DirectoryServices.ActiveDirectoryRights] $confADRight
    $aceType = [System.Security.AccessControl.AccessControlType] "Allow"
    $aceInheritanceType = [System.DirectoryServices.ActiveDirectorySecurityInheritance] "Descendent"
    $ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($aceIdentity, $aceADRight, $aceType, $confDelegatedObjectType, $aceInheritanceType)
 
    # Apply ACL
    $delegationGroupACL.AddAccessRule($ace)
    Set-Acl -Path "AD:\$OrganizationalUnit" -AclObject $delegationGroupACL
}
 
# Calling the function
Set-Delegation -OrganizationalUnit "OU=My,OU=Servers,DC=contoso,DC=com" -DelegationGroupName "global-server-admins-full"

Using the function as it is written above would set Full Control for members of the security group “global-server-admins-full” for all descendent objects (00000000-0000-0000-0000-000000000000) of the Organizational Unit “OU=My,OU=Servers,DC=contoso,DC=com” but not for the OU itself. Therefore, Users of the security group “global-server-admins-full” cannot modify or delete the OU itself.

How to Install Active Directory on a Windows Server 2016 Core using PowerShell

How to add a freshly installed Windows Server 2016 Core to a domain and promote it as Domain Controller in a few easy steps.
In this scenario we assume that there already is an existing domain in an existing forest and the new Domain Controller should just be added to the existing domain.

Rename the Computer properly

1
Rename-Computer -NewName dc-w2016

Restart the computer to make the renaming effective

1
Restart-Computer

Configure an IP Adresse
Therefore you need to know the name of the network interface you want to use. Get a list of all network interfaces using:

1
Get-NetAdapter

Configure the IP Address

1
New-NetIPAddress -InterfaceAlias MyInterface -IPAddress 192.168.1.20 -PrefixLength 24 -AddressFamily IPv4 -DefaultGateway 192.168.1.1

Configure the DNS Server
To successfully join the new computer to the domain and promote it to a Domain Controller, the DNS Server entries should point to already existing Domain Controllers

1
Set-DnsClientServerAddress -InterfaceAlias MyInterface -ServerAddresses [IP_of_existing_DC]

Add the computer as a member to the specific domain

1
Add-Computer -DomainName lab.mydaomain.com

Insert the credentials of a Domain administrator account when prompted.

Restart the computer to make the domain join effective

1
Restart-Computer

Note: from this point on you can easily remote administer your computer using the Remote Server Administration Tools (RSAT) from any computer in your network

Now install the Active Directory Domain Services (ADDS) Features
Using the switch -IncludeManagementTools installs the management tools.

1
Install-WindowsFeature AD-Domain-Services -IncludeManagementTools

Finally promote the computer as a Domain Controller
The switch -InstallDns installs the DNS Server Role on the computer and integrates it with Active Directory

1
Install-ADDSDomainController -DomaiName lab.mydaomain.com -InstallDns

After restarting the computer (there will be a prompt), the computer has successfully been joined to the domain and promoted as a Domain Controller.

certutil – Generate a Certificate Template to OID Hashtable

In order to use certutil to list certificates issued from a specific certificate template as shown below, you have to know the templates OID.

1
certutil -view -restrict 'Certificate Template=<certificate_template_OID>'

The following PowerShell script returns a hashtable with the template name as the key and the OID as the value for each template found either on the Active Directory (-adtemplate switch) or on the local Certification Authority (CA) (-catemplates switch).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Prepare variables
$certutil = "$($env:SystemRoot)\system32\certutil.exe"
$templateHash = @{}
$currentTemplateName = $false
 
# Get certutil stdout, select the displayname and msPKI-Cert-Template-OID strings and walk through them in a loop
Invoke-Expression "$certutil -adtemplate -v" | select-string displayname, msPKI-Cert-Template-OID | foreach {
 
    # Check if the template name variable is set and the current value is an OID
    if($currentTemplateName -ne $false -and $_ -match 'msPKI-Cert-Template-OID'){
 
        $oid = $_ -replace '([\w|-]*)\s=\s([\d|.]*)(.*)','$2'
        $templateHash.add($currentTemplateName, $oid)
        $currentTemplateName = $false
    }
 
    # Check if the current value is a template name
    elseif($_ -match 'displayname'){
 
        $currentTemplateName = $_ -replace 'displayname = ',''
    }
}
 
# Print Hastable
$templateHash | fl

Password Complexity Validation with PowerShell

Sometimes you need to verify if a password meets some minimal requirements such as length, upper- and lowercase characters and special chars.

This simple script validates if a string / password matches at least these minimum requirements:

  • At least one uppercase character
  • At least one lowercase character
  • At least one digit
  • At least one special char
  • At least 10 characters in length
1
2
3
4
5
6
7
8
9
10
11
12
13
$password = 'mySecure!P@ssword$'
 
$counter = 0
@('[A-Z]', '[a-z]', '\d', '[\41-\57\100\133-\140]', '.{10,}') | foreach {
    if(($str -creplace $_, '') -ne $str) { $counter++ }
}
 
if($counter -ge 5){
    Write-Host "Strong password"
}
else {
    Write-Host "Weak password"
}