Enable Windows Update “Features on Demand” and “Turn Windows features on or off” in WSUS Environments

I Found this website very usefull and searched long for this.

If you are running Microsoft Windows in a domain environment with WSUS configured, you may notice that you’re not able to install some FODs (Features on Demand), or use the “Turn Windows features on or off”. This will stop you from installing things like the RSAT tools, .NET Framework, Language Speech packs, etc…

You may see “failure to download files”, “cannot download”, or errors like “0x800F0954” when running DISM to install packages.

To resolve this, you need to modify your domain’s group policy settings to allow your workstations to query Windows Update servers for additional content. The workstations will still use your WSUS server for approvals, downloads, and updates, however in the event content is not found, it will query Windows Update.

Enable download of “Optional features” directly from Windows Update

  1. Open the group policy editor on your domain
  2. Create a new GPO, or modify an existing one. Make sure it applies to the computers you’d like
  3. Navigate to “Computer Configuration”, “Policies”, “Administrative Templates”, and then “System”.
  4. Double click or open “Specify settings for optional component installation and component repair”
  5. Make sure “Never attempt to download payload from Windows Update” is NOT checked
  6. Make sure “Download repair content and optional features directly from Windows Update instead of Windows Server Update Services (WSUS)” IS checked.
  7. Wait for your GPO to update, or run “gpupdate /force” on the workstations.

Please see an example of the configuration below:

Download repair content and optional features directly from Windows Update instead of Windows Server Update Services (WSUS)

You should now be able to download/install RSAT, .NET, Speech language packs, and more!

Install Fonts with Powershell

$ssfFonts = 0x14

$fontSourceFolder = ""

$Shell = New-Object -ComObject Shell.Application

$SystemFontsFolder = $Shell.Namespace($ssfFonts)

$FontFiles = Get-ChildItem $fontSourceFolder

$SystemFontsPath = $SystemFontsFolder.Self.Path

$rebootFlag = $false

 

foreach($FontFile in $FontFiles) {

    # $FontFile will be copied to this path:

    $targetPath = Join-Path $SystemFontsPath $FontFile.Name

    # So, see if target exists...

    if(Test-Path $targetPath){

        # font file with the same name already there.

        # delete and replace.

        $rebootFlag = $true

        Remove-Item $targetPath -Force

        Copy-Item $FontFile.FullName $targetPath -Force

    }else{

        #install the font.

        $SystemFontsFolder.CopyHere($FontFile.fullname)

    }

}

 

#Follow-up message

if($rebootFlag){

    Write-Host "At least one existing font overwritten. A reboot may be necessary."

}

Disable-Enable automapping Echange 2016

Because automapping is not always working correct, just created this script to re-enable automapping with the correct settings. This script you need to run on the Exchange server.

# Created by Daag van der Meer
# blog.van-daag.nl
# This script gives the user full access to the mailbox. This will update also the folders below the inbox with the rights.

Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn;


# Enter the mailbox name here
$mailbox= "<mailboxname>"

# Add here the usernames like "<USERNAME>", "<ÜSERNAME>"
$users= "<USERNAME>", "<ÜSERNAME>"


####### Start of the Script. Do not edit below

foreach ($user in $users){ 
# First disable AutoMapping
Add-MailboxPermission -Identity $mailbox -User $user -AccessRights FullAccess -InheritanceType All -Automapping $false


# Now enable Automapping
Add-MailboxPermission -Identity $mailbox -User $user -AccessRights FullAccess -InheritanceType All -Automapping $true
} 

 

AD Send mail on password reset

This is based on Security Event ID 4724. When this is logged on the domain controller, Task Scheduler kicks this script. And send a mail to Admin and user. And also creates a local log file who reset the password.

# Created by Daag van der Meer on 12-10-2018
# Blog.van-daag.nl
# Powershell Send mail When account password reset is done To user and admin.
# Save this also in a Log file
 
##################
## Temp location for creating HTML email
##################
$Report= "c:\Temp\reset.html" 

##################
## Log location
##################
$log= "C:\Logs\Accountreset.csv"
 
$HTML=@" 
<title>Account locked out Report</title> 
<!--mce:0--> 
"@ 

##################
## Retrieve eventlog with all value
##################

$event = Get-EventLog -LogName Security -InstanceId 4724 -Newest 1 |
 Select TimeGenerated, ReplacementStrings |
  % { 
     New-Object PSObject -Property @{ 
      "Account name" = $_.ReplacementStrings[0] 
      "Account Domain" = $_.ReplacementStrings[1] 
      "Reset by" = $_.ReplacementStrings[4] 
      Date = $_.TimeGenerated 
    } 
   } 

##################
## Retrieve eventlog For filter username
##################

$userevent= Get-EventLog -LogName Security -InstanceId 4724 -Newest 1 | Select-Object @{n='UserName';e={$_.ReplacementStrings[0]}}
$user= $userevent -replace ".*=" -replace "}"

##################
## send mail to admin
##################


$event | ConvertTo-Html -Property "Account name","Account Domain","Reset By",Date -head $HTML -body  "<H2> User account password is reset</H2>"| 
     Out-File $Report -Append 

##################
## Mail config admin
##################

$MailBody= Get-Content $Report 
$MailSubject= "User password reset" 
$SmtpClient = New-Object system.net.mail.smtpClient 
$SmtpClient.host = "<MAIL SERVER>" 
$MailMessage = New-Object system.net.mail.mailmessage 
$MailMessage.from = "<FROM MAILADRESS>" 
$MailMessage.To.add("<MAILADRESS>") 
$MailMessage.Subject = $MailSubject 
$MailMessage.IsBodyHtml = 1 
$MailMessage.Body = $MailBody 
$SmtpClient.Send($MailMessage) 

del c:\Temp\reset.html
$event | Export-Csv $log -NoTypeInformation -Append


#############################
### Send mail to user #######
#############################

$useremail = Get-ADUser $user -Properties mail | Select-Object -ExpandProperty mail
$userfirstname1 = Get-ADUser $user -Properties GivenName | Select-Object GivenName
$userfirstname = $userfirstname1 -replace ".*=" -replace "}"
$userlastsname1 = Get-ADUser $user -Properties Surname | Select-Object Surname
$userlastsname = $userlastsname1 -replace ".*=" -replace "}"

$Pic = '<ADD LOCATION FOR PICTURE IN MAIL>'

$att1 = new-object Net.Mail.Attachment($Pic)
$att1.ContentType.MediaType = “image/png”
$att1.ContentId = “Attachment”

##################
## HTML mail setup to user
##################

$userBody = @"
<html>
    <body>
    <span lang=NL style='font-size:10.0pt;line-height:106%;color:black'>
Dear $userfirstname $userlastsname,<br>
<br>
The password for your <b>DOMAIN\$user</b> account has been reset.<br>
If you did not request this, please inform:<br>
<br>
This is an automated email.<br>
<br>
</span>
<img src="cid:Attachment">
"@

##################
## Mail config user
##################

$userSubject = "Your password is changed"
$userMessage = New-Object system.net.mail.mailmessage 
$userMessage.from = "<FROM MAILADRESS>"
$userMessage.To.add("$useremail")  
$userMessage.Subject = $userSubject  
$userMessage.IsBodyHtml = 1
$userMessage.Body = $userBody 


$userMessage.Attachments.Add($att1)


$SmtpClient.Send($userMessage)

 

AD Send mail on Account Lock

At a company where I worked, there was no logging with account lock and the had plans to change the GPO that accounts will not be auto unlocked.
So I also added mailing to the admin of that specific OU (Country)

I found a script from Maxzor1908 on Technet
That was the basic. I Added a lot of extra.

# Powershell User Account locked out Maxzor1908 *16/4/2013* 
# Checked and edit by Daag van der Meer - 03-10-2018
# blog.van-daag.nl
#              Email adress needs to be filled in at the admin account.
 
##################
## Temp location for creating HTML email
##################
$Report= "c:\Temp\Lockedhtml.html" 

##################
## Log location
##################
$log= "C:\Logs\AccountLocked.csv"
 
$HTML=@" 
<title>Account locked out Report</title> 
<!--mce:0--> 
"@ 
 
$Account_Name = @{n='Account name';e={$_.ReplacementStrings[-1]}} 
$Account_domain = @{n='Account Domain';e={$_.ReplacementStrings[-2]}} 
$Caller_Computer_Name = @{n='Caller Computer Name';e={$_.ReplacementStrings[-1]}} 
 
##################
## Retrieve eventlog with all value
##################

             
$event= Get-EventLog -LogName Security -InstanceId 4740 -Newest 1 | 
   Select TimeGenerated,ReplacementStrings,"Account name","Account Domain","Caller Computer Name" | 
   % { 
     New-Object PSObject -Property @{ 
      "Account name" = $_.ReplacementStrings[-7] 
      "Account Domain" = $_.ReplacementStrings[5] 
      "Caller Computer Name" = $_.ReplacementStrings[1] 
      Date = $_.TimeGenerated 
    } 
   } 
    
  $event | ConvertTo-Html -Property "Account name","Account Domain","Caller Computer Name",Date -head $HTML -body  "<H2> User is locked in the Active Directory</H2>"| 
     Out-File $Report -Append 
 

##################
## Retrieve eventlog For filter username
##################


 $user= Get-EventLog -LogName Security -InstanceId 4740 -Newest 1 | 
   Select ReplacementStrings | 
   % { 
     New-Object PSObject -Property @{ 
      "Account name" = $_.ReplacementStrings[-7] 
      } 
   } 

$userrename = $user -replace ".*=" -replace "}"
$userou = Get-ADUser $userrename -Properties DistinguishedName | Select-Object -ExpandPropert DistinguishedName

##############################
## Here is the ad Groups configured who can unlock accounts
#############################
 

if ($userou.Contains('OU=<OU>')) {$mail = "<AD GROUP>"}

elseif ($userou.Contains('OU=<OU>')) {$mail = "<AD GROUP>"}

else {$mail = "<AD GROUP>" }

$adminmail = Get-ADGroupMember $mail | select samaccountname | %{Get-ADUser $_.samaccountname -Properties mail} | %{write-output "$($_.mail)"}
$mailadmin =  $adminmail -join "," -replace ",,"

##################
## Mail config admin
##################


$MailBody= Get-Content $Report 
$MailSubject= "User Account locked out" 
$SmtpClient = New-Object system.net.mail.smtpClient 
$SmtpClient.host = "<MAIL SERVER>" 
$MailMessage = New-Object system.net.mail.mailmessage 
$MailMessage.from = "<FROM MAIL ADRESS>" 
$MailMessage.To.add("<TO MAIL ADRESS>,$mailadmin") 
$MailMessage.Subject = $MailSubject 
$MailMessage.IsBodyHtml = 1 
$MailMessage.Body = $MailBody 
$SmtpClient.Send($MailMessage) 


##################
## Remove the temp document
##################
del c:\Temp\Lockedhtml.html

##################
## Write to log about the account lock
##################

$event | Export-Csv $log -NoTypeInformation -Append

AD Change Display name

At the company were I worked we had a name change. They also use the display name in outlook to send mail. Example: Daag van der Meer [Company] So everyone see direct what the company is.

The script below built the display name with firstname lastname [Company]

# Script created by Daag van der Meer
# Blog.van-daag.nl

Import-Module ActiveDirectory

#creates a list of all users (change all between <>
$allUsers = Get-ADUser -Filter * -SearchBase 'ou=Users,ou=<OU>,DC=<DC>,DC=<DC' -Properties cn,displayName

 
# Add your company name or something else after username 
$hi = "<company>"

 

foreach ( $u in $allUsers | Where-Object { ($_.givenName) -and ($_.surName) } ) {

    $fn = $u.givenName.Trim()

    $ln = $u.surName.Trim()

   

    Write-Host $fn $ln

    Set-ADUser -Identity $u -DisplayName "$fn $ln $hi" -GivenName "$fn" -SurName "$ln"-PassThru |

        Rename-ADObject -NewName "$fn $ln $hi"

}