Few of the articles are posted as Images, Please use Laptop / Computers to go through the articles for best experience. For phone users, switch to Web Version

Please Share with your colleagues if you found these blogs informative. Happy Learning :-)

Youtube Tutorials || For more refer below links -

Windows Server Video Links

Patch Installation via Command line in Windows Servers - YouTube

Tutorial4 Converting Windows Server Evaluation to Full Version (youtube.com)

Resetting Local Admin Password on Windows Servers (youtube.com)


Active Directory Video Links

Move FSMO Roles via Command Line - YouTube

Active Directory - Lost and Found Conflict - YouTube

Active Directory - Fine Grain Password Policy - YouTube

Restricting Domain Users from Joining Workstations to the Domain (youtube.com)

LAPS Implementation (youtube.com)

Forcefully Demotion of a Domain Controller (youtube.com)


Setting up Practical LABS Video Links

Tutorial 1 Getting Started with LAB Design || Downloading Setups || Vmware Workstation Installation (youtube.com)

Tutorial2 - VM Creation || Windows Server Installation || Sysprep (youtube.com)

Tutorial 3 - Setting up first Windows Server using Generalized template - YouTube

Tutorial 4 Converting Windows Server Evaluation to Full Version (youtube.com)

Tutorial5 Setting up Windows Servers with Basic Postconfiguration (youtube.com)

Tutorial6 Promoting First Domain Controller (youtube.com)

Tutorial7 Using Windows Server as a Router (youtube.com)

Tutorial8 Promoting DC with Higher OS / Upgrading DC to a Higher OS (youtube.com)




Powershell Script - AD User Account & Password related details

 <#Read Me

Script Usage - Finding UserID password related details such as -

1. Password Expired or not ?

2. If Expired, then on which day it's going to expired ?

3. How many days left before it expires ?

4. Whether UserId is active or not ?


Note - Input.txt contains Samaccountname of all the users against which you are looking to get info.

Input.txt should be in the same location of script.

Refer Userdetails_$date.csv for detailed output.


**************************************************************************#>


$inputuserids = Get-Content ./Input.txt

$date = $(Get-Date -Format "dd_MM_yyy")+".csv"

foreach($userid in $inputuserids)

{

    try{


Get-ADUser -Identity $userid -Properties Displayname,msDS-UserPasswordExpiryTimeComputed,PasswordExpired,Enabled,`

Passwordlastset | Select Displayname,Samaccountname,@{n="AccountStatus";e={if($($_.Enabled) -eq $true){"Active"}else{"Disabled"}}},`

Passwordlastset,PasswordExpired,@{n="ExpiryDate";e={[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")}},`

@{n="DaysLeft";e={(New-TimeSpan -Start $(Get-Date) -End $([datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed"))).Days}}`

| Export-Csv ./Userdetails_$date.csv -NoTypeInformation -Append


}

catch

{

$userid | Select-Object -Property @{n="Displayname";e={"NA"}},@{n="Samaccountname";e={$userid}},@{n="AccountStatus";e={"NA"}},@{n="Passwordlastset";e={"NA"}},@{n="PasswordExpired";e={"NA"}},@{n="ExpiryDate";e={"NA"}},@{n="DaysLeft";e={"NA"}}| Export-Csv ./Userdetails_$date.csv -NoTypeInformation -Append


}


}

Sample Output





Powershell Script - New AD Groups Creation from .CSV File

Few weeks back, I got a task to create multiple AD Groups from a CSV file. Below is a dummy look of a CSV that i got.



<#Read me !!

1. Make sure columns heading mentioned in Input file should not be altered.

2. In below case, i am taking details such as Group name, Path, scope description from Input.csv.

3. Logs_date.csv file can also be referred for detailed output.

***********************************************************************#>

$groupdetails = Import-Csv .\Input.csv

$date = $(Get-Date -Format "dd_MM_yy")+".csv"

foreach($group in $groupdetails)

{

    try

    {

    New-ADGroup -Name $group.Name -GroupScope $group.Scope -GroupCategory $group.Category -Path $group.Path -Description $group.Description -PassThru  | Select Name,@{n=("Status");e={("Created under")}},DistinguishedName | Export-Csv ./Logs_$date -Append -NoTypeInformation

    }


catch

    {

       $group | Select-Object -Property @{n=("Name");e={($group.Name)}},@{n=("Status");e={("already exist under ")}},@{n="DistinguishedName";e={((Get-ADGroup -Identity $group.Name).DistinguishedName)}} | Export-Csv ./Logs_$date -Append -NoTypeInformation

        }

}

Sample Output after Groups creation















Powershell Script - Checking SMB1 Feature Status on Windows Servers

$servers = @("DDC01","DMMS01","DMMS02","DDC02","FakeServer","Tempvm4") #Listing all servers in " " quotes. Take input from a file if server count is large.

$date = (Get-Date -Format "dd_MM_yyyy")+".html"

$outputHTML = "<HTML>

<Body><Table border='2'>

<h2> SMB1 Status Report Started at $(Get-Date)</h2>

<TR><Td>Name</Td><Td>Operating System</Td><Td>DistinguishedName</Td>s

<Td>SMB1Status</Td></Tr>"


foreach($server in $servers)

{

$server = $server.trim()

$error.Clear()

try{

$command1 = Get-ADComputer -Identity $server -Properties OperatingSystem,DistinguishedName | Select-Object -Property Name,OperatingSystem,DistinguishedName -ErrorAction Stop 

}

catch{

$command1 = "Error"

}

try{

$command2 = Invoke-Command -ComputerName $server -ScriptBlock{(Get-WindowsOptionalFeature -Online -FeatureName SMB1Protocol).State} -ErrorAction Stop

}


catch{

$command2 = "Error"

}

if(($command1 -eq "Error")) 

    {

    $outputHTML += "<TR style='background-color:orange'>"

     $outputHTML += "

    <TD>$($server)</TD>

    <TD>$("NA")</TD>

    <TD>$("NA")</TD>

    <TD>$("Unable to fetch, please check manually")</TD>

    </TR>"

    }

    elseif(($command2 -eq "Error"))

    {

    $outputHTML += "<TR style='background-color:orange'>"

     $outputHTML += "

    <TD>$($server)</TD>

    <TD>$($command1.OperatingSystem)</TD>

    <TD>$($command1.DistinguishedName)</TD>

    <TD>$("Unable to fetch, please check manually")</TD>

    </TR>"

   }

else

    {

    $command3 = $command1 | Select-Object -Property Name,OperatingSystem,DistinguishedName,@{n="SMB1Status";e={$command2}}

        if(($($command3.SMB1Status.Value) -eq "Disabled"))

        {

        $outputHTML += "<TR style='background-color:red'>"

        }

        else

        {

        $outputHTML += "<TR>"

        }


   $outputHTML += "

    <TD>$($command3.Name)</TD>

    <TD>$($command3.OperatingSystem)</TD>

    <TD>$($command3.DistinguishedName)</TD>

    <TD>$($command3.SMB1Status.Value)</TD>

    </TR>"

    }

}


$outputHTML += "</Table></Body></Html>"

$outputHTML += "<h2> SMB1 Status Report Ended at $(Get-Date) </h2>"

$outputHTML | Out-File ./SMB1Status_$date



Sample Output






Powershell Script - Windows Servers User Profile Status Check :: Cleanup Project

<#Created By Abhishek Bansal

Read Note 

Script Usage :: Useful in finding out all the domain profiles created under C:\Users on Windows Servers is Enabled or Not in AD.

Pre requisites :: Copy all the code into a text file, save it with an extension ".PS1". Once saved, run it as Administrator.

Execution & Outputs :: Output will be displayed in ProfileID_Status.csv #>


$srv = Read-Host "Enter Name or IP address of the Server = "

$Profile = Get-ChildItem "\\$srv\c$\Users" -Exclude "Public","Administrator*",".Net*","MSSQL*","Temp*"   #Mention any other local profile that you want to exclude.

foreach($row in $Profile.Name){

    $row = $row.Trim()

    try{

    Get-ADUser -Properties * $row | Select-Object -Property Displayname,Samaccountname,@{n="Status";e={$_.Enabled}},whenChanged,PasswordExpired,LastLogonDate | Export-Csv ./ProfileID_Status.csv -Append -NoTypeInformation

    }

    catch

    {

    $row | Select-Object -Property @{n="Displayname";e={"NA"}}, @{n="Samaccountname";e={$row}},@{n="Status";e={"ID is either local/disabled or doesn't exist in AD"}}, @{n="whenChanged";e={"NA"}}, @{n="PasswordExpired";e={"NA"}}, @{n="LastLogonDate";e={"NA"}} | Export-Csv ./ProfileID_Status.csv -Append -NoTypeInformation

    }

}


Sample Output



Powershell Script - Exporting GPO Settings in HTML

<#Read Me

Script Usage - Backing/Exporting GPO settings into HTML format.

Script Workflow

1. We can either use a ".txt" file as an Input file containing GPO's which we want to export.

2. Incase, we want to export all the GPO's in the domain, then use "Get-GPO" cmdlet with -All switch.

3. Outputs will be created in GPOname.html 

******************************************************************************#>


#Script 1 - Exporting all the GPO's in the domain.

$gpo = Get-GPO -All

foreach($item in $gpo)

{

$gponame = $item.DisplayName

Get-GPOReport -Name $gponame -ReportType HTML | Out-File ./$gponame.html

}


#Script 2 - Exporting all the GPO's mentioned in 'InputGPOdetails.txt' file.

#Note - Have this file under same folder where Script is kept.


$InputGPOdetails = Get-Content ./InputGPOdetails.txt

foreach($gponame in $InputGPOdetails)

{

Get-GPOReport -Name $gponame -ReportType HTML | Out-File ./$gponame.html

}

Blocking User to Use MFA - Entra ID

Use Case - I have a user named "Clouduser2" which was configured to use Azure Portal after providing MFA. Now i am being told to Block MFA for Clouduser2 due to security breach by him/her, in other words blocking access for Clouduser2.

Below are the steps

1. Firstly, i will verify whether User is configured & capable to use MFA or not. For that, navigate to below path -

Entra ID --> Security --> Authentication Methods --> Activity --> User Registration details --> Sort by Multi factor authentication --> ID's showing as Capable are configured for MFA.

2. For Blocking Clouduser2, i will search Multifactor Authenticator on the search bar.

Under Multifactor authenticator --> Click on Block/Unblock Users --> Click on Add --> Provide user detail, reason for blocking & Save.


























3. We can now test the results. Clouduser2 while login will see below error & he/she won't be able to login simply because MFA is not working.





















Troubleshooting Password Hash Sync Issue - Entra ID

Recently, I had a weird situation where I was not able to use my On-premise AD account to login to Azure Portal.

Azure AD connect Sync was not showing any errors and i was able to see my On-premise account in Azure portal also but for some reason when i was trying to login to portal.azure.com, I was getting incorrect password error.

I checked logging in with another Onprem account & it was still showing me the same error. Definitely issues seems for multiple accounts.

Below steps followed for fix -

1. Since the error was related to Incorrect password, so no way it could be due to things like Conditional access because CA are checked once the user is authenticated (i.e Authorization after authentication ).
2. I opened Powershell Launcher from Azure AD Connect.
Open Azure AD Connect --> Configure --> Select Troubleshoot --> Next --> Launch




3. Onprem accounts are already syncing to Entra ID, i have chosen Option 2 which will do checks against Passwords syncing to Entra ID from On-premise.

4. In this case, I suspect issues for multiple On-premise account & hence I have chosen option 1 which is "Password Hash Synchronization doesn't work at all". 
If there is a specific account for which issue is reported, then we can go for Option 2 / Option3.



5. Post selecting option1, it will do certain tests such as Checking if Password sync is Enabled in your tenant or On premises, Password Sync is running for the connector etc.

In below output, it's clear that Password Sync is enabled but it's not running for Local / Onprem AD Connector & this is what causing the incorrect password issue. Password typed while login was correct but since it's not getting sync to Entra ID, it is not able to authenticate the Onprem ID.




I pressed "Y" & it restarted the Password Hash Sync for the AD Connector. Post this, issue got resolved.

Stop Syncing Onprem AD Users to Entra ID using Sync Rule Editor

Use case - Stop Syncing Onprem AD Users to Entra ID.

Example - I have bunch of Users naming Dummyuser1, Dummyuser2, .... Dummyuser10 & initially there are syncing to Entra ID.

I also have an Onprem AD Group named "DenySyncingADUsers_Cloud". I need to implement a scenario where Users named "Dummyuser1, Dummyuser2 , Dummyuser3 & Dummyuser9" should not be Syncing to Entra ID.


Initial View






























Steps

1. Login to your AzureAD Connect Server & Navigate to Sync rule Editor ( Start --> Search for Synchronization Rule Editor )

2. Choose direction as Inbound since this rule is from Onprem to Entra AD & click on Add New rule.















3. Fill the below details - 

Name - Name of the Rule
Description - Brief description about the rule.
Connected System - Onprem Domain
Connected System Object Type - What's the object type in Onprem domain for which you are creating the rule. ( User )
Metaverse Object Type - What the object type in Entra AD for which you are creating the rule. (Person)
Link Type - Join
Precedence - Priority of the rule.

















4. Once filled, click next & apply Scoping filter.

Scoping would be - DN is member of "AD Group". This means any object that is member of "AD Group" would be considered under this rule.

In this case it would be : "User Object DN" is member of "DenySyncingADUsers_Cloud DN"


















5. We will leave the Join rules as it is. Under Transformations, we can set a constant "Cloudfiltered" to true. This means any object that is impacted due to this rule will have Cloudfiltered set to "TRUE"..









6. Click Finish. Rule would be created. You need to wait for the next Sync cycle to run or you can manually trigger the Sync as well.

7. Testing the results. First adding the accounts that we don't want to Sync anymore.











8. Initiating Manual Sync using below command






9. Observing the results. You won't see Dummyuser1,2,3 & 9 in Entra AD now post Sync.

















Patch Installation via Command Line

Two Step Process
1. Expand "*.MSU" file & extract all the files within it.
2. Using "*.CAB" file against DISM command for installation.

Steps
1. I have a .Net Patch on my desktop. To start with the installation, I will first navigate to my patch location using CD command. ( In this example, it's under desktop )
























2. Once done, Expand the "*.MSU" file using below command.
Syntax - Expand -f:* "MSUFile" "Pathwhere you want to extract.

In this case, i have created a folder name "ExtractedCAB" & i will be extracting all the files inside this folder.




















3. We will now navigate inside the "ExtractedCAB" using CD command again & use the main CAB file against DISM command to deploy the patch.

Command - Dism.exe / Online /Add-Package /PackagePath: "CABfilelocation"
















4. Once done, it will ask for restart, Press Y & post reboot verify Patch installation status either using Control panel or through cmdlets such as Get-hotfix.










Stopped-extension-DLL-exception / no-start-ma Error

I faced a strange issue few days back when i was trying to  force a Delta sync it gave me "Stopped-extension-DLL-exception / no-start-ma" errors.





Steps taken for fix -

1. Using Global Administrator credentials, I logged into Azure Portal. I quickly check the Sign in logs & noticed some Failure events & on exploring them, i found possible reasons under Additional details.

Possible reasons could be a Policy blocking the access. Policy could be a coming from Conditional access or from Identity Protection .















2. Navigate to Security feature under EntraAD --> Cross checked if in past, any conditional access policy was created that might block access.

3. I then verified Azure Identity Protection Policy & under Sign-in risk Policy, i did have a Policy which was configured for Testing purpose. 

Policy was about if the Sign in risk is Low & above, then for all users access would be blocked.
















I disabled that policy & tried forcing the Sync. This time, it got completed successfully.






Stopped-deletion-threshold-exceeded error while running Azure AD Sync

 Fixing - Stopped-deletion-threshold-exceeded error while doing Sync.









Possible Reasons - I am getting this error particularly because i have Un synced an OU from AzureAD Connect & that OU contains items which was above threshold limit for Object Sync & Unsync. 

In order to fix it, we will login to Azure AD connect server & run below commands -

1. Get-ADSyncExportDeletionThreshold - Check ADSyncExport Deletion threshold currently set.

Currently it's set to 50. This means if there is an OU which contains more then 50 objects, then probably it would throw the error.




2. Editing threshold from 50 to 200 since the OU i am unsyncing right now contains total 153 objects.





Once done, try forcing the sync again & this time you won't see any error.






Powershell Script - Finding Group Membership differences b/w two ID's in AD

 #Created By - Abhishek Bansal
#Use Case - Useful in finding membership differences b/w two ID's. ( Mirroring Group membership)
#Note - This won't do any modification in Group membership. This only fetches the membership, compares them & give us the output in a CSV file.
#Below is the Script, Copy paste it into Powershell ISE & run it directly.



$sourceid = Read-Host "Enter Source ID from which would be used for mirroring = "
$requestorid = Read-Host "Enter requestor ID whicn needs to be mirrored = "

$Sourceid_Data = Get-ADPrincipalGroupMembership -Identity $sourceid | Select SamAccountName,GroupScope,GroupCategory,objectClass
$requestorid_data = Get-ADPrincipalGroupMembership -Identity $requestorid | Select SamAccountName,GroupScope,GroupCategory,objectClass

$counter = 0
$totalcounter = $Sourceid_Data.Count
$percentagecomplete = 0
foreach($Sourceid_entry in $Sourceid_Data)
{
$counter++
$percentagecomplete = ($counter/$totalcounter)*100
Write-Progress -Activity "Comparing values" -Status "$counter checking" -PercentComplete $percentagecomplete
    foreach($Sourceid_entry1 in $requestorid_data)
    {
        if(($Sourceid_entry.SamAccountName -eq $Sourceid_entry1.SamAccountName))
        {
            $flag = 1   
            break
        }  
        else
        {
            $flag = 0
        }
     }
     if($flag -eq 0)
     {
     
 $Sourceid_entry | Select @{n="SamAccountName";e={$Sourceid_entry.SamAccountName}},@{n="GroupScope";e={$Sourceid_entry.GroupScope}},@{n="GroupCategory";e={$Sourceid_entry.GroupCategory}},@{n="objectClass";e={$Sourceid_entry.objectClass}},@{n="distinguishedName";e={$Sourceid_entry.distinguishedName}} | Export-Csv .\Differences_$sourceid.csv -NoTypeInformation -Append
     }
  }


Moving FSMO Roles via Command line

 Listing all the FSMO roles at once via different ways -
Command 1- net dom query fsmo










Command 2 - Listing Domain Wide FSMO roles


Command 3 - Listing Forest wide FSMO roles








As per all above snaps, we can find out which DC's are holding different FSMO roles.
Our task would be to move Schema & Infrastructure master role from "DDC01" to another DC named "GDC01".

Below command will be used for movement.

Syntax 
Move-ADDirectoryServerOperationMasterRole -Identity "DestinationDC" -OperationMasterRole 'FSMO Roles separated by comma'




  
We can then check again & this time we will see those two roles on another DC.







Syncing / Unsyncing an OU from Azure AD Connect

 Scenario-

I have an OU named "Dummy OU" containing 3 sub OU's. At present all 3 Sub OU's are syncing but as per requirements i have to Unsync  one of the Sub OU named "Dummy Groups".

Solution

First, we will open Azure AD Connect. Connect to Azure AD by providing 'Global Admin' Credentials of your tenant.










Connect to OnPrem AD
















Next would be unselect "Dummy Groups" OU under Domain and OU filtering















We will then proceed & Click on Configure. Incase you don't want to initiate the syn right now, uncheck it.





 







Powershell Script - Removing Members (Users / Groups) from AD Group.

 #Created By - Abhishek Bansal

<#Read Me !! 

1. Script Usage - Removing Members (Users & Groups ) mentioned in Input.txt from AD Group.

2. Incase of Access Denied, run ISE as Administrator & make sure account used should have sufficient rights to remove User id from AD Group.

For using it on any other server, just copy the entire folder, edit .ps1 into PS ISE & run it. #>


$grp = Read-Host "Enter AD Group Name = "

Get-ADGroupMember -Identity $grp | Select Name,Samaccountname | Export-Csv ./BeforeRemoval_Membership_$grp.csv -NoTypeInformation -Append

$users = Get-Content .\Input.txt

$line = 0

$linecount = $users.Count

$percentagecomplete= 0

$filename = "Output_"+(Get-Date -Format "yyyy_MM_dd")+".csv"

foreach($userid in $users)

    {

    $line++

    $percentagecomplete = $line / $linecount * 100

    $error.Clear()

    $userid = $userid.Trim()

   Write-Progress -Activity "Removing Users..." -PercentComplete $percentagecomplete -Status "$line out of $linecount"

    try{

          Remove-ADGroupMember -Identity $grp -Members $userid -Confirm:$false

     $userid | Select-Object -Property @{n="Samaccountname";e={$userid}}, @{n="Status";e={"$userid removed succesfully on $(get-date)" }}  | Export-csv ./$filename -NoTypeInformation -Append

    }

catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException]

    {

    $userid | Select-Object -Property @{n="Samaccountname";e={$userid}}, @{n="Status";e={$error.exception.message}} | Export-csv ./$filename -NoTypeInformation -Append

    }

}

Get-ADGroupMember -Identity $grp | Select Name,Samaccountname | Export-Csv ./AfterRemoval_Membership_$grp.csv -NoTypeInformation -Append


Powershell Script - Fetching LAPS Password from AD

 #Created By - Abhishek Bansal 

#Time Stamp - Saturday, April 1, 2023 9:27:17 AM

<#Read Me !! 

1.Script will fetch LAPS Password from AD.

2.Try Catch block is used to filter out non existing computer objects. Refer commnets as "Computer object not found" in the last column.

3.Last column blank means that computer object LAPS password is not there in AD.

For using it on any other server, just copy the entire folder, edit .ps1 into PS ISE & run it. 

#>


$inputdata = Get-Content .\Input.txt

$line = 0 

$linecount = $inputdata.count

$percentagecomplete= 0

$filename = "Output_"+(Get-Date -Format "yyyy_MM_dd")+".csv"

foreach($server in $inputdata)

{

$line++

$percentagecomplete = ($line / $linecount) * 100

$server = $server.trim()

Write-Progress -Activity "Fetching Laps Password.." -PercentComplete $percentagecomplete -Status "$line out of $linecount"

    try{

       Get-ADComputer -Identity $server -Properties * | Select Name,OperatingSystem,CanonicalName,ms-Mcs-AdmPwd  | Export-Csv ./$filename -NoTypeInformation -Append

               }

    catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException]

 {

     $server | Select @{n="Name";e={$server}},@{n="OperatingSystem";e={"NA"}},@{n="CanonicalName";e={"NA"}},@{n="ms-Mcs-AdmPwd";e={"Computer object not found"}} | Export-Csv ./$filename -NoTypeInformation -Append

    }

}