Categories
Lab

Create your AD Lab with Powershell

Recently i have been labing a lot, and most of the labs requires me to have an Active directory for various stuff like authentication with Cisco ISE and ASA VPN also been into System Center Configuration Manager.

In the midst of all this i had to automate and make it easy for me to spin up an Active directory server, this all made me turn back to Powershell which is an awesome tool from Microsoft. With my knowldge on coding never thought it will be that tough, with google and Powershell documentation as my friend there will be no mountain to high for me to climb.

Luckily i came across an this article that was describing how to do that excatly.

How to create your Active Directory Lab with Powershell. We are working with the latest Windows Server 2019 version aka 1809, We use Standard version with GUI, but you can run all this step in a Windows Server Core this is more secure to my mind, but you need have a remote Windows 10 with RSAT.

In my Lab I use free API https://randomuser.me/ for create random user in my Active Directory.

1. Configure Windows Server 2019

1.1 Networking

How to configure networking with powershell.

#Find the Interface Index for your NIC with the name Ethernet
$InterfaceIndex = $(Get-NetIPAddress | Where-Object {$_.InterfaceAlias -like "Ethernet*"}).InterfaceIndex

#Assign Address IPv4
New-NetIPAddress -InterfaceIndex $InterfaceIndex -AddressFamily IPv4 -IPAddress “172.17.0.1” –PrefixLength 16 -DefaultGateway 172.17.255.254

#Assign Server DNS
Set-DnsClientServerAddress -InterfaceIndex $InterfaceIndex  -ServerAddresses 172.17.0.1

1.2 ComputerName

Rename-Computer -NewName DC -Restart 

1.3 Install WindowsFeature

  • The first step is to install Ad-Domain-Services.
Get-WindowsFeature -Name *AD-Domain*

  • Install the Feature with all subfeatures
Install-WindowsFeature -Name AD-Domain-services -IncludeAllSubFeature -IncludeManagementTools

  • Verify all the Feature installed
Get-WindowsFeature | Where-Object {$_. installstate -eq "installed"} | Format-List Name,Installstate | more

The Output :

Name         : AD-Domain-Services
InstallState : Installed

Name         : FileAndStorage-Services
InstallState : Installed

Name         : File-Services
InstallState : Installed

Name         : FS-FileServer
InstallState : Installed

Name         : Storage-Services
InstallState : Installed

Name         : NET-Framework-45-Features
InstallState : Installed

Name         : NET-Framework-45-Core
InstallState : Installed

Name         : NET-WCF-Services45
InstallState : Installed

Name         : NET-WCF-TCP-PortSharing45
InstallState : Installed

Name         : GPMC
InstallState : Installed

Name         : RSAT
InstallState : Installed

Name         : RSAT-Role-Tools
InstallState : Installed

Name         : RSAT-AD-Tools
InstallState : Installed

Name         : RSAT-AD-PowerShell
InstallState : Installed

Name         : RSAT-ADDS
InstallState : Installed

Name         : RSAT-AD-AdminCenter
InstallState : Installed

Name         : RSAT-ADDS-Tools
InstallState : Installed

Name         : WoW64-Support
InstallState : Installed

Name         : Windows-Defender
InstallState : Installed

Name         : PowerShellRoot
InstallState : Installed

Name         : PowerShell
InstallState : Installed

Name         : PowerShell-ISE
InstallState : Installed

Name         : XPS-Viewer
InstallState : Installed


2. Create Active Directory Forest

For Create Forest you have one powershell cmdlet `Install-ADDSforest’. the full documentation is available here. The function accept many parameters in my Lab, I use the minimal parameter to quickly promote my domain controller.

#Secure my password
$Password ="123+aze"
$SecurePassword = $Password | ConvertTo-SecureString -AsPlainText -Force

# Promote the domain controller
Install-ADDSForest -DomainName JM2K69.pwsh -SafeModeAdministratorPassword $SecurePassword -Force

The Output 👩‍💻:

WARNING: Windows Server 2019 domain controllers offer a default security setting named "Allow encryption algorithms compatible with Windows NT 4.0". This setting prevents the use of weak encryption algorithms when establishing secure channel sessions.
 
For more information on this setting, see Knowledge Base article 942564 (http://go.microsoft.com/fwlink/?LinkId=1
04751).
 
WARNING: It is not possible to create a delegation for this DNS server because the authoritative parent zone cannot be found or it is not running the Windows DNS server. If you are integrating with an existing DNS infrastructure, you must manually create a delegation with this DNS server in the parent zone to enable reliable name resolution outside of the "JM2K69.pwsh" domain. Otherwise, no action is required.
 
WARNING: Windows Server 2019 domain controllers provide a default security setting named "Allow encryption algorithms compatible with Windows NT 4.0". This setting prevents the use of weak encryption algorithms when establishing secure channel sessions.
 
For more information on this setting, see Knowledge Base article 942564 (http://go.microsoft.com/fwlink/?LinkId=1
04751).

Then you computer restart.

3. Create your Organizational Unit (OU)

Now that the domain controller is up and running, you can start creating OUs. they allow to organize the objects of your company (Users, Computers, Printers …). On these organizational units will be positioned the GPOs.

ComputerSection

3.1 PowerShell Time

At first, the script must be able to work on any ADDS. This code below allows us to retrieve all the information needed to create objects in active directory.

$fqdn = Get-ADDomain
$fulldomain = $fqdn.DNSRoot
$domain = $fulldomain.split(".")
$Dom = $domain[0]
$Ext = $domain[1]

3.2 Create one OU

Th powershell Cmdlet for create OU is very simple :

New-ADOrganizationalUnit -Name Test -Description Test

In your Lab Only and not in Production you can add the -parameter -ProtectedFromAccidentalDeletion $false you can easily remove the OU.

3.3 My Script

# Informations
$Sites = ("Lyon","New-York","London")
$Services = ("Production","Marketing","IT","Direction","Helpdesk")
$Materiel = ("Computer","Server","Printers")
$FirstOU ="Sites"

New-ADOrganizationalUnit -Name $FirstOU -Description $FirstOU  -Path "DC=$Dom,DC=$EXT" -ProtectedFromAccidentalDeletion $false


foreach  ($S in $Sites)
{
        New-ADOrganizationalUnit -Name $S -Description "$S"  -Path "OU=$FirstOU,DC=$Dom,DC=$EXT" -ProtectedFromAccidentalDeletion $false

     foreach ($Serv in $Services)
     {
        New-ADOrganizationalUnit -Name $Serv -Description "$S $Serv"  -Path "OU=$S,OU=$FirstOU,DC=$Dom,DC=$EXT" -ProtectedFromAccidentalDeletion $false
     }

 }

4. Create User

I Create a function to use a free API.

function New-RandomUser {
    <#
        .SYNOPSIS
            Generate random user data from Https://randomuser.me/.
        .DESCRIPTION
            This function uses the free API for generating random user data from https://randomuser.me/
        .EXAMPLE
            Get-RandomUser 10
        .EXAMPLE
            Get-RandomUser -Amount 25 -Nationality us,gb 
        .LINK
            https://randomuser.me/
    #>
    [CmdletBinding()]
    param (
        [Parameter(Position = 0)]
        [ValidateRange(1,500)]
        [int] $Amount,

        [Parameter()]
        [ValidateSet('Male','Female')]
        [string] $Gender,

        # Supported nationalities: AU, BR, CA, CH, DE, DK, ES, FI, FR, GB, IE, IR, NL, NZ, TR, US
        [Parameter()]
        [string[]] $Nationality,

        [Parameter()]
        [ValidateSet('json','csv','xml')]
        [string] $Format = 'json',

        # Fields to include in the results.
        # Supported values: gender, name, location, email, login, registered, dob, phone, cell, id, picture, nat
        [Parameter()]
        [string[]] $IncludeFields,

        # Fields to exclude from the the results.
        # Supported values: gender, name, location, email, login, registered, dob, phone, cell, id, picture, nat
        [Parameter()]
        [string[]] $ExcludeFields
    )

    $rootUrl = "http://api.randomuser.me/?format=$($Format)"

    if ($Amount) {
        $rootUrl += "&amp;results=$($Amount)"
    }

    if ($Gender) {
        $rootUrl += "&amp;gender=$($Gender)"
    }

    if ($Nationality) {
        $rootUrl += "&amp;nat=$($Nationality -join ',')"
    }

    if ($IncludeFields) {
        $rootUrl += "&amp;inc=$($IncludeFields -join ',')"
    }

    if ($ExcludeFields) {
        $rootUrl += "&amp;exc=$($ExcludeFields -join ',')"
    }
    Invoke-RestMethod -Uri $rootUrl
}

4.1 How to use the function

How to :

$users = New-RandomUser -Amount 30 -Nationality us -IncludeFields name,dob,phone,cell -ExcludeFields picture | Select-Object -ExpandProperty results

foreach ($user in $users) {
    $newUserProperties = @{
        Name = "$($user.name.first) $($user.name.last)"
        City = "City"
        GivenName = $user.name.first
        Surname = $user.name.last
        Path = $adPath
        title = "Director"
        department="IT"
        OfficePhone = $user.phone
        MobilePhone = $user.cell
        Company="JM2K69"
        EmailAddress="$($user.name.first).$($user.name.last)@$($adDomain)"
        AccountPassword = (ConvertTo-SecureString $userPassword -AsPlainText -Force)
        SamAccountName = $($user.name.first).Substring(0,1)+$($user.name.last)
        UserPrincipalName = "$(($user.name.first).Substring(0,1)+$($user.name.last))@$($adDomain)"
        Enabled = $true
    }

    try {New-ADUser @newUserProperties}
    catch {}
}


5. The final Script

All the part combined in one. For The different site I change the -parameter Nationality. In this example I create 20 Employees and 5 Directors / Sites / Services.

$fqdn = Get-ADDomain
$fulldomain = $fqdn.DNSRoot
$domain = $fulldomain.split(".")
$Dom = $domain[0]
$Ext = $domain[1]
$userPassword = '123+aze'
$Sites = ("Dar-Es-Salaam", "Arusha", "Dodoma", "Zanzibar", "Mwanza")
$Services = ("Production", "Marketing", "IT", "Direction", "Helpdesk")
$Material = ("Computer", "Server", "Printers")
$FirstOU = "Sites"
 
New-ADOrganizationalUnit -Name $FirstOU -Description $FirstOU  -Path "DC=$Dom,DC=$EXT" -ProtectedFromAccidentalDeletion $false
 
 
foreach ($S in $Sites) {
    New-ADOrganizationalUnit -Name $S -Description "$S"  -Path "OU=$FirstOU,DC=$Dom,DC=$EXT" -ProtectedFromAccidentalDeletion $false
  
    foreach ($Serv in $Services) {
        New-ADOrganizationalUnit -Name $Serv -Description "$S $Serv"  -Path "OU=$S,OU=$FirstOU,DC=$Dom,DC=$EXT" -ProtectedFromAccidentalDeletion $false
       
        switch ($S) {
            'Dar-Es-Salaam' {
                $Employees = New-RandomUser -Amount 20 -Nationality fr -IncludeFields name, dob, phone, cell -ExcludeFields picture | Select-Object -ExpandProperty results
                $Directors = New-RandomUser -Amount 5 -Nationality fr -IncludeFields name, dob, phone, cell -ExcludeFields picture | Select-Object -ExpandProperty results
            }
            'Arusha' {
                $Employees = New-RandomUser -Amount 20 -Nationality us -IncludeFields name, dob, phone, cell -ExcludeFields picture | Select-Object -ExpandProperty results
                $Directors = New-RandomUser -Amount 5 -Nationality us -IncludeFields name, dob, phone, cell -ExcludeFields picture | Select-Object -ExpandProperty results
            }
            'Dodoma' {
                $Employees = New-RandomUser -Amount 20 -Nationality gb -IncludeFields name, dob, phone, cell -ExcludeFields picture | Select-Object -ExpandProperty results
                $Directors = New-RandomUser -Amount 5 -Nationality gb -IncludeFields name, dob, phone, cell -ExcludeFields picture | Select-Object -ExpandProperty results
            }
            'Zanzibar' {
                $Employees = New-RandomUser -Amount 20 -Nationality us -IncludeFields name, dob, phone, cell -ExcludeFields picture | Select-Object -ExpandProperty results
                $Directors = New-RandomUser -Amount 5 -Nationality us -IncludeFields name, dob, phone, cell -ExcludeFields picture | Select-Object -ExpandProperty results
            }
            'Mwanza' {
                $Employees = New-RandomUser -Amount 20 -Nationality gb -IncludeFields name, dob, phone, cell -ExcludeFields picture | Select-Object -ExpandProperty results
                $Directors = New-RandomUser -Amount 5 -Nationality gb -IncludeFields name, dob, phone, cell -ExcludeFields picture | Select-Object -ExpandProperty results
            }
            Default { }
        }
 
        foreach ($user in $Employees) {
            $newUserProperties = @{
                Name              = "$($user.name.first) $($user.name.last)"
                City              = "$S"
                GivenName         = $user.name.first
                Surname           = $user.name.last
                Path              = "OU=$Serv,OU=$S,OU=$FirstOU,dc=$Dom,dc=$EXT"
                title             = "Employees"
                department        = "$Serv"
                OfficePhone       = $user.phone
                MobilePhone       = $user.cell
                Company           = "$Dom"
                EmailAddress      = "$($user.name.first).$($user.name.last)@$($fulldomain)"
                AccountPassword   = (ConvertTo-SecureString $userPassword -AsPlainText -Force)
                SamAccountName    = $($user.name.first).Substring(0, 1) + $($user.name.last)
                UserPrincipalName = "$(($user.name.first).Substring(0,1)+$($user.name.last))@$($fulldomain)"
                Enabled           = $true
            }
 
            Try { New-ADUser @newUserProperties }
            catch { }
 
        }
        foreach ($user in $Directors) {
            $newUserProperties = @{
                Name              = "$($user.name.first) $($user.name.last)"
                City              = "$S"
                GivenName         = $user.name.first
                Surname           = $user.name.last
                Path              = "OU=$Serv,OU=$S,OU=$FirstOU,dc=$Dom,dc=$EXT"
                title             = "Directors"
                department        = "$Serv"
                OfficePhone       = $user.phone
                MobilePhone       = $user.cell
                Company           = "$Dom"
                EmailAddress      = "$($user.name.first).$($user.name.last)@$($fulldomain)"
                AccountPassword   = (ConvertTo-SecureString $userPassword -AsPlainText -Force)
                SamAccountName    = $($user.name.first).Substring(0, 1) + $($user.name.last)
                UserPrincipalName = "$(($user.name.first).Substring(0,1)+$($user.name.last))@$($fulldomain)"
                Enabled           = $true
            }
 
            Try { New-ADUser @newUserProperties }
            catch { }
        }
    }
}

Written by Jérôme Bezet-Torres @JM2K69.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.