Archive for the ‘Windows Server’ Category

A subinacl is Windows command line utility used to manage Share and NTFS permissions.

I used AMDT tool to migrate users, groups,shares and computer objects from one domain to another, during computer migration, i choose to retain old and to add new permissions so users from both domains can access to shares during migration process.

In my case source domain is source.local and destination domain is destination.local and i had shared and NTFS permsissions from both domains.


We first need to export shared and NTFS permissions to file

cd "C:\Program Files (x86)\Windows Resource Kits\Tools"
Subinacl /noverbose /output=C:\NTFSPermissions.txt /subdirectories "C:\SHARE\*.*"

Subinacl /noverbose /output=C:\SharedPermissions.txt /share "\\FS\SHARE"

# or Subinacl /outputlog="c:\outputlog.txt"  /Subdirectories C:\SHARE*.*  /changedomain=source=destination

Then remove entries for old domain (source.local)

subinacl /playfile C:\NTFSPermissions.txt /replacestringonoutput=source=destination

subinacl /playfile C:\SharedPermissions.txt/replacestringonoutput=source=destination

Adding new domain ACE’s entries to shared and NTFS permissions

In case we didn’t use AMDT to migrate fileserver computer, ie, we just copied shared folder together with permissions

ROBOCOPY "\\source\sharelocation" "\\destination\sharelocation" /MIR /SEC /LOG:location:\nameoflogfile.

Only ACE entries from source (old) domain is present

In that case, we can use /migratetodomain subinacl switch to add ACE entries of new domain to shared and NTFS permissions.

# add ACE entries to root folder only
Subinacl /outputlog="c:\outputlog.txt"  /subdirectories "C:\SHARE"  /migratetodomain=source=destination

# add ACE entries to subfolder/files

Subinacl /outputlog="c:\outputlog.txt"  /subdirectories "C:\SHARE\*.*"  /migratetodomain=source=destination

In order to issue SSL certificate on behalf of another user we first need Enrollment Agent Certificate,in order to create it, we need to copy Enrollment Agent certificate template.

Creating and issuing of Enrollment Agent Certificate

In Certification authority console, under Certificates templates, right click on Certificate templates-Manage

Right click “Enrollment Agent”-Duplicate template

Under Cryptography tab make sure Microsoft Enhanced Cryptography Provider V1.O is selected,minimum key size:2048

Under Request handling, check “Allow private key to be exported”

Under security tab make sure Authenticated users have rights “Read” and “Enroll”.

Right click Certificate Templates-New-Certificate Template to Issue

Select template and click OK.

Configuring certificate template for enrollment

On certificate which should be enrolled to users, right click-Properties-Issuance requirements tab

This number of authorized signatures:1

Policy type required in signature:Application policy

Application policy:Certificate request agent

Enrollment of Enrollment Agent Certificate

On your workstation machine open Certificate console,Expand Personal,right click on Certificates-All tasks-Request New Certificate

Click Next twice and select certificate we just issued-Enroll

Issuing certificate for other user

On your workstation machine open Certificate console,Expand Personal,right click on Certificates-All tasks-Advanced operations-Enroll of behalf of

In signing certificate page click browse-certificate should pop-up automatically

Select certificate you want to issue to user.

When asked for user click browse, in Location specify domain and type user for which you need to issue certificate. You can issue cert only for one user.

Enrollment agents

Enrollment agents are users who can issue certificates for other users.

On CA machine, open Certification Authority console, right click on machine name-Properties-Enrollment agents.

Here you can specify who can issue specific templates.

Powershell script for issuing multiple SSL certificates

This script issues certificated for multiple enabled AD users (search filter can be modified)

function GenerateSSLCert {
    param (
    $PKCS10 = New-Object -ComObject X509Enrollment.CX509CertificateRequestPkcs10
    # Certificate template name for issuing to users
    $pkcs7 = New-Object -ComObject X509enrollment.CX509CertificateRequestPkcs7
    $pkcs7.RequesterName = "test\$userName"
    $signer = New-Object -ComObject X509Enrollment.CSignerCertificate
    # Thumbrint of Enrollment Agent certificate
    $pkcs7.SignerCertificate = $signer
    $Request = New-Object -ComObject X509Enrollment.CX509Enrollment

Get-ADUser -SearchBase "OU=Users,DC=test,DC=local" -filter * | Where { $_.DistinguishedName -notmatch  "OU=DisabledUsers|OU=OpenVPNUsers|OU=ServiceUsers" -and $_.Enabled -eq $True } | ForEach-Object {
      $user = $_.SamAccountName
      GenerateSSLCert $user 
      Write-Host $_.Exception.Message
      Write-Host "SSL certicate not created for user:$user"

In order for user to be able to make VPN with global protect, SSL certificate needs to be installed on machine, also, username specified in certificate subject must exist on On-premise domain controller.

In this example certificates are issued from internal Certificate authority.

Generating certificate for PaloAlto firewall

We need SSL to issue certificate assigned to public DNS name of firewall.

Device-certificates-device certificates-generate

Click the checkbox next to the Certificate Name or any whitespace on that line to select it and click export certificate

File with csr extension will be created, copy that file to Certification authority machine, open cmd and run certreq -submit -attrib "CertificateTemplate:template_name" where “template_name” is the name of Certification template.

You’ll be prompted for csr file

Then select certification authority

Certificate will be created with cer extension.

Copy certificate to machine on which you created certificate request. Now

click on Device-certificates-device certificates on PaloAlto web interface, click import in bottom panel.

Certificate screen 6 - 7.1.png

In the Import Certificate dialog, type the name of the pending certificate. It must match exactly the name we used when created certificate request

Importing CA root certificate

On Certificate authority open MMC-Local computer-Trusted root Certification Authority-Certificates-right click on CA certificate-all tasks-export-select Base-64 encoded

Save file with cer.extension

On PaloAlto Device-certificates-device certificates-import

Creating LDAP profile

Specify Domain controllers for user authentication

Device-server profile-Add-type:active-directory, specify Domain controllers,base DN for user search and service account and password for searching AD.

Creating Authentication profile

Device-Authentication profile-Add

Specify Login Active directory Attribute, select LDAP as type and select LDAP profile created in previous step

Creating Certificate profile

Device-certificate manager-Certificate profile-Add

In Username field select Subject Alt and select Email or UserPrincipal name, this means that PaloAlto get username from SSL certificate and it will be automatically populated in GlobalProtect username field.

In Advanced tab select Security group for VPN users. Users who need VPN need to be members of this group.

Creating SSL/TLS profiles

This profile defines which SSL certificate will be used and SSL version

Device-Certificate management-SSL/TLS Service profile-Add

Specify PaloAlto SSL certificate we generated and uploaded in one of previous steps and minimal TLS version.

GlobalProtect portal configuration


On general page select publicy accessible interface and IP address

In Authentication tab specify SSL/TLS Service profile we created in previous step,Certificate profile and click Add

Specify authentication profile

In Agent tab,uder Agent,click Add

In Authentication tab,For Client Certificate select Local and select PaloAlto FW certificate

In External tab specify DNS name of PaloAlto firewall

Click OK, now under Agent tab-Under Trusted Root CA click Add

Network-GlobalProtect-Gateways-Add and add CA root certificate we created earlier.

Configuring GlobalProtect Gateway


Specify PaloAlto firewall publicly accessible interface and IP address

Under Authentication tab select SSL/TLS Service profile and certificate profile and click Add

Select Authentication profile, set name and click OK

Under Agent tab specify tunnel settings

Under Client setting specify IP pools and Access routes

Under Network Services specify primary and secondary DNS servers

Commit changes

Generating user certificates

Now we need to create and issue SSL certificates for users who will connect to VPN using global protect

On Issuing certificate authority, in Certification authority console, right click on Certificate templates-Manage

Certification Templates console will launch, right click on template User-duplicate template.

In tab Subject Name make sure settings are as in picture bellow

In General tab select validity period, once done,click OK.

In security tab, make sure Domain users have rights to Enroll and Read.

Once all is set click OK, right click Certificate Templates-New-Certificate Template to Issue

Select template and click OK.

Installing SSL certificate on user computers

To use VPN, install GlobalProtect software,.

Open Local computer certificate store (start-run-certlm.msc).Expand Personal,right click on Certificates-All tasks-Request New certificate,select Certificate template and install certificate

Now you should be able to initiate VPN connection

Rsync on Windows

Posted: June 22, 2020 in Windows Server

Rsync, which stands for “remote sync”, is a remote and local file synchronization tool. It uses an algorithm that minimizes the amount of data copied by only moving the portions of files that have changed.It’s native linux command, but thanks to Cygwin, we can use it on Windows too.

Installing Cygwin on Windows

Cygwin is a Unix-like environment and command-line interface for Microsoft Windows.It’s a repository of open source software compiled with this dll. In other words, it’s package manager of Linux command line tools which can be run on Windows.

Download cygwin and run installation, in View select Full, in searchbox type rsync, and select rsync under Net category, check Src, and choose version under New

Do the same for openssh (Windows 10 and Server 2019 have this package shipped)

Click next to install both packages.

By default, cygwin is installed on C:\cygwin64 folder, tools are in bin folder

Creating SSH keys (keypair) on Windows

In order to copy files from Windows to Linux we need to authenticate on Linux box, either using credentials or ssh keys. I find ssh more convenient authentication type, so we need to create private and public key on Windows and copy public key to linux machine.

Creating ssh keys

Open Cygwin

Create keys


Copy content of C:\cygwin64\home\Administrator.ssh\ to linux box (/root/.ssh/authorized_keys file)

In cygwin terminal type


Test access from Windows to linux. In this example is IP of Linux machine, userame root

ssh root@

Copy files from Windows to Linux

In this example we’ll copy content of C:\inetpub folder to /data folder on Linux box

Again, from cygwin terminal type

rsync -avm //localhost/c$/inetpub/ root@

Simple copy usually is not enough, we need to set ownership and permission on the destination.

There are three basic file system permissions, or modes, to files and directories:

  • read (r)
  • write (w)
  • execute (x)

Each mode can be applied to these classes:

  • user (u)
  • group (g)
  • other (o)

The user is the account that owns the file. The group that owns the file may have other accounts on the system as members. The remaining class, other (sometimes referred to as world), means all other accounts on the system.

To see all permissions on files and folder use following command: ls -l /folder

Following command sets read (r) for user (u),and read (r),write (w) and execute (x) for group (g ) and set ownership to user root and group root.

rsync -avm --chmod=u=r --chown=root:root //localhost/c$/inetpub/ root@

ls -l /data/
total 0
dr--rwx--- 3 root root 19 Jun 22 10:22 custerr
dr-------- 4 root root 64 Jun 22 10:24 history
dr--rwx--- 3 root root 22 Jun 22 10:22 temp
dr--rwx--- 2 root root 44 Jun 22 10:22 wwwroot

Following command will give user (u) and group (g) read (r) and execute (x) permission on destination folder, and set ownership to user root and group root.

rsync -avm --chmod=ug=rx --chown=root:root //localhost/c$/inetpub/ root@

ls -l /data/
total 0
dr-xr-x--- 3 root root 19 Jun 22 10:22 custerr
dr-xr-x--- 4 root root 64 Jun 22 10:24 history
dr-xr-x--- 3 root root 22 Jun 22 10:22 temp
dr-xr-x--- 2 root root 44 Jun 22 10:22 wwwroot

Following command will set read (r) and write (w) permissions to user (u),group(g) and all (o) group, ownership to user root and password root

rsync -avm --chmod=ugo=rw --chown=root:root //localhost/c$/inetpub/ root@

ls -l /data/
total 0
drw-rw-rw- 3 root root 19 Jun 22 10:22 custerr
drw-rw-rw- 4 root root 64 Jun 22 10:24 history
drw-rw-rw- 3 root root 22 Jun 22 10:22 temp
drw-rw-rw- 2 root root 44 Jun 22 10:22 wwwroot

To avoid copying permissions to destination, it’s enough to omit -a switch in rsync command. To copy empty directories use –rWH switches and omit -m switch.

In order to execute above command from command prompt/Powershell, add C:\cygwin64\bin to system path environmental variable

By default, LDAP communications (port 389) between client and server applications are not encrypted. This means that it would be possible to use a network monitoring  device or software and view the communications traveling between LDAP client and server computers. LDAP over SSL/TLS (LDAPS-port 636) is automatically enabled when you install an Public key (PKI) infrastructure, (Certificate Authority-CA). In this post i wan’t cover installing and configuring PKI infrastructure, i’ll concentrate on enabling LDAPS on windows and configuring secure connection to Windows Domain controllers from linux machines using SSL certificates.

Creating Certificate templates

On Issuing certificate authority, in Certification authority console right click on Certificate templates-Manage

Certification Templates console will launch, right click on template Kerberos Authentication-duplicate template

In compatibility tab,make sure that for Compatibility settings Windows Server 2003 is specified

In Request handling tab, make sure Signature and encryption is selected for purpose

If you plan to import the certificate into the Active Directory Domain Services certificate store, then should also mark the private key as exportable.

In general tab, specify validity period and template name

In subject name tab make sure DNS name and Service principal nane (SPN) are checked in.

In security tab, make sure Domain controllers are added and Enroll, Read and Autoenroll (if you want this template is enrolled automatically) are set to Allow

Once all is set click OK, right click Certificate Templates-New-Certificate Template to Issue

Select template and click OK

Exporting Certification authority (CA) certificate

On CA machine we issued certificate, name of this CA will be written in that certificate, so we need to export personal certificate of this CA and transfer it to Linux machine.This certificate will be used to validate certificate of Domain controller we are going to enroll in next steps.

Open Local computer certificate store (start-run-certlm.msc)

Expand Personal,right click on Certificates-All tasks-Export

Select No, do not export private key, for format select Base-64 encoded X.509 (.CER)

Save certificate to file with cer extension and move it to Linux machine

Enrolling certificate to Domain Controller

Now we need to enroll Certificate we just issued on Certification Authority machine.Go to Domain controller,open Local computer certificate store (start-run-certlm.msc)

Expand Personal,right click on Certificates-All tasks-Request New Certificate

Click Next twice and select certificate we just issued-Enroll

Exporting Domain controller certificate to Linux machine

Now we need to export this enrolled certificate to Linux machine.

Right click on certificate we just enrolled-All tasks-Export

Select No, do not export private key, for format select Base-64 encoded X.509 (.CER)

Save certificate as cer file and move it to linux machine

Exporting Trusted Root Certification authority (CA) certificate

In case you’re using intermediate CA (as in my case), you need to export Trusted Root certification authority certificate also, again, in Computer certificate store, expand Trusted root certification authorities-click Certificates-right click om Root certificate-export

Export in same way as in previous steps

Testing LDAPS connection – Windows

Before moving to linux, let’s first test LDAP over SSL connection.

On Domain controler from command prompt, type ldp.exe, click on Connection tab-Connect..

Type DNS name, port 636, check SSL and click OK

If all is OK, connection should be sucessfull

ld = ldap_sslinit("dc.example.local", 636, 1);
Error 0 = ldap_set_option(hLdap, LDAP_OPT_PROTOCOL_VERSION, 3);
Error 0 = ldap_connect(hLdap, NULL);
Error 0 = ldap_get_option(hLdap,LDAP_OPT_SSL,(void*)&lv);
Host supports SSL, SSL cipher strength = 256 bits
Established connection to dc.example.local.
Retrieving base DSA information…
Getting 1 entries:

Testing LDAPS connection – Linux

Certification authority certificate is exported to /etc/pki/tls/certs/issuingca.cer,domain controller certificate is exported to /etc/pki/tls/certs/dc.cer and trusted root CA to /etc/pki/tls/certs/ca.cer

Add CA Root and issuing CA certs to Linux (CentOS) ca store

cp /etc/pki/tls/certs/issuingca.cer /etc/pki/ca-trust/source/anchors
cp /etc/pki/tls/certs/ca.cer /etc/pki/ca-trust/source/anchors
update-ca-trust enable
update-ca-trust extract

# verify:
openssl verify /etc/pki/ca-trust/source/anchors/issuingca.cer
openssl verify /etc/pki/ca-trust/source/anchors/ca.cer

Test connection:

openssl s_client -connect test.local:636 -CAfile /etc/pki/tls/certs/ca.cer

depth=2 CN =  CA-ROOT
verify return:1
depth=1 DC = local, DC = test, CN = CA
verify return:1
depth=0 CN = dc.test.local
verify return:1
Certificate chain
 0 s:CN = dc.test.local
   i:DC = local, DC = test, CN = CA
 1 s:DC = local, DC = test, CN = CA
   i:CN = CA-ROOT
Server certificate

Apache – configuring LDAPS authentication

cat /etc/http/conf.d/ssl.conf

LDAPTrustedMode SSL

LDAPTrustedGlobalCert CERT_BASE64 /etc/pki/tls/certs/ca.cer

<Directory "/var/www/cgi-bin">

    LDAPTrustedClientCert CERT_BASE64 /etc/pki/tls/certs/dc.cer
    AllowOverride None
    Options None
    Order allow,deny
    Allow from all
    AuthType Basic
    AuthName "login to continue"
    AuthBasicProvider ldap
    AuthLDAPBindAuthoritative off
    AuthLDAPURL "ldaps://test.local:636/dc=test,dc=local?sAMAccountName
    AuthLDAPBindDN "bindtest@test.local"
    AuthLDAPBindPassword "pass"
    require valid-user


Creating certificate request

  1. “Certificate Signing Request” (CSR) is generated using the public key and some information about the identity.
  2. The certification authority uses information from the CSR, its own public key, authorization information, and a “signature” generated by its private key to issue a certificate.

On linux machine, create certification request including subject alternate name:

openssl req -new -sha256 -nodes -days 1095 -out \nagios.csr -newkey rsa:2048 -keyout \nagios.key -config <(                            
cat <<-EOF
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn
[ dn ]
CN =
[ req_ext ]
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = nagios.test.coml
IP.1 =

Transfer csr file to Windows Issuing Certificate Authority

On CA, list available templates:


Generate certificate

certreq -submit -attrib "CertificateTemplate:template_name"

You’ll be prompted for csr file

Then select certification authority

Certificate will be created with cer extension

Now move file to linux system and copy cer and key files to path specified in configuration files

Below script worked fine up to Ubuntu 18 because that distro introduced netplan.

Function Set-VMNetworkConfiguration {
    Param (
        [String[]]$DefaultGateway = @(),
        [String[]]$DNSServer = @(),
    $VM = Get-WmiObject -Namespace 'root\virtualization\v2' -Class 'Msvm_ComputerSystem' | Where-Object { $_.ElementName -eq $NetworkAdapter.VMName } 
    $VMSettings = $vm.GetRelated('Msvm_VirtualSystemSettingData') | Where-Object { $_.VirtualSystemType -eq 'Microsoft:Hyper-V:System:Realized' }    
    $VMNetAdapters = $VMSettings.GetRelated('Msvm_SyntheticEthernetPortSettingData') 
    $NetworkSettings = @()
    foreach ($NetAdapter in $VMNetAdapters) {
        if ($NetAdapter.Address -eq $NetworkAdapter.MacAddress) {
            $NetworkSettings = $NetworkSettings + $NetAdapter.GetRelated("Msvm_GuestNetworkAdapterConfiguration")
    $NetworkSettings[0].IPAddresses = $IPAddress
    $NetworkSettings[0].Subnets = $Subnet
    $NetworkSettings[0].DefaultGateways = $DefaultGateway
    $NetworkSettings[0].DNSServers = $DNSServer
    $NetworkSettings[0].ProtocolIFType = 4096
    if ($dhcp) {
        $NetworkSettings[0].DHCPEnabled = $true
    } else {
        $NetworkSettings[0].DHCPEnabled = $false
    $Service = Get-WmiObject -Class "Msvm_VirtualSystemManagementService" -Namespace "root\virtualization\v2"
    $setIP = $Service.SetGuestNetworkAdapterConfiguration($VM, $NetworkSettings[0].GetText(1))
    if ($setip.ReturnValue -eq 4096) {
        while ($job.JobState -eq 3 -or $job.JobState -eq 4) {
            start-sleep 1
        if ($job.JobState -eq 7) {
            write-host "Success"
        else {
    } elseif($setip.ReturnValue -eq 0) {
        Write-Host "Success"


Get-VMNetworkAdapter -VMName Ubuntu18| Set-VMNetworkConfiguration -IPAddress -Subnet -DNSServer -DefaultGateway


Netplan is based on YAML based configuration system that makes configuration process very simple. Netplan has replaced the old configuration file /etc/network/interfaces that we previously used for configuring network interfaces in Ubuntu.

As result, i wasn’t able to set Ubuntu 18.04 VM IP address from Hyper-V host.

Install Hyper-V tools on Ubuntu VM:

sudo apt-get update 
sudo apt-get install linux-image-virtual linux-tools-virtual linux-cloud-tools-virtual
sudo reboot now

Check if Hyper-V daemon is running:

systemctl status hv-kvp-daemon
● hv-kvp-daemon.service - Hyper-V KVP Protocol Daemon
   Loaded: loaded (/lib/systemd/system/hv-kvp-daemon.service; enabled; vendor preset: enabled)
   Active: active (running) since Wed 2020-02-12 09:07:53 UTC; 37min ago
 Main PID: 1463 (hv_kvp_daemon)
    Tasks: 1 (limit: 1054)
   CGroup: /system.slice/hv-kvp-daemon.service
           └─1463 /usr/lib/linux-tools/4.15.0-76-generic/hv_kvp_daemon -n

Check if there is any error message:

tail /var/log/syslog

If you get following errors:

sh: 1: /usr/libexec/hypervkvpd/hv_get_dns_info: not found
sh: 1: /usr/libexec/hypervkvpd/hv_get_dhcp_info: not found

Copy hyper-v daemon binaries to location mentioned in errors:

find /usr/|grep hv_set_ifconfig
mkdir -p /usr/libexec/hypervkvpd/
cp /usr/sbin/hv_* /usr/libexec/hypervkvpd
systemctl restart hv-kvp-daemon

Disabling netplan

/usr/sbin/hv_set_ifconfig is python script which accepts IP, address, default gateway, network mask and DNS server as input parameters from Hyper-V host and edit /etc/network/interfaces file. I tried changing python script to edit /etc/netplan/50-cloud-init.yaml but it doesn’t work from Hyper-V host, so i disabled netplan completely

Edit /etc/default/grub file and add following line:


update grub configuration


Remove netplan and config files:

apt purge
rm -rf /usr/share/netplan/*
rm -rf /etc/netplan/*

Install ifupdown

apt install ifupdown

Configure interface:

vi /etc/network/interfaces

auto eth0
iface eth0 inet static
dns-search lan

Although we specified DNS servers in /etc/network/interfaces, it will be overwritten on reboot, to set DNS server permanently, edit /etc/systemd/resolved.conf :

DNS= 2001:4860:4860::8888 2001:4860:4860::8844

Reboot Ubuntu VM

shutdown -r now

Now try to change IP address using Powershell code from begining of this post and you should be able to change Ubuntu 18 VM IP address

Let’s presume we have some PowerShell script for editing DNS entry, and we need to run it as Scheduled Task under some service account .

Add service account “Log on As Batch Job” right by using GPO:

  • Click START and type Group Policy then click on Group Policy ManagementEither edit the existing GPO that contains existing USER RIGHTS ASSIGNMENT (likely Default Domain Policy) or right click and CREATE AND EDIT a new policy
  • Expand Computer Configuration > Policies > Windows Settings > Security Settings > Local Policies > User Rights Assignment node
  • Double click Log on as a batch job
  • Click the Add User or Group button and add your service account user


In case you still get “This Task Requires That The User Account Specified Has Log On As Batch Job Rights” warning in task scheduler, add user to Backup Operators group.

Then add user to DNSAdmins group.

If script needs to be executed from remote machine:

Enabling Remote Management

  • add service account to WinRMRemoteWMIUsers__ on the DNS Server/DC.
  • On the Windows desktop, right-click Windows PowerShell on the taskbar, and then click Run as Administrator.
  • On the Windows start screen, right-click Windows PowerShell, and then on the app bar, click Run as Administrator.
  • type the following, and then press Enter to enable all required firewall rule exceptions.

Configure-SMremoting.exe -enable


Open Computer Management: start > run > compmgmt.msc

Expand Services and Applications – right click WMI Control – Properties – Security tab – click Security


Add service account

In the applies to, choose “this namespace and subnamespace” and Click “Allow” for Execute Methods and Enable Account.

If script needs to be run remotely, click “Allow” also for Remote Enable


For remote access:

In WMI Control expand root – cimv2 – Security


Add the group WinRMRemoteWMIUsers__ as the principal, then click ok.

In the applies to, choose “this namespace and subnamespace”

Add service account and Click “Allow” for Execute Methods, Enable Account and Enable Remote

Restart Windows Management Instrumentation service

Server 2016

CentOS 8 required Generation 2 VM,

Choose Generation 2 because legacy hardware, like the tulip NIC are no longer supported, gen 2 will avoid the use of legacy hardware emulation.

Specify Memory, Disk and VM name, after machine is create it will be turned off. Right click VM – Settings.. – Security Secoore Boot Enabled Select Microsoft UEFI Certificate Authority under Template

Start VM

Select “Edition” you want to install

VM will be installed

Server 2012 R2

Specify Generation 2, allocate memory and HDD space,don’t turn on VM. While VM is turned off, in VM properties select Firmware-Secure Boot, uncheck “Enable Secure Boot

Start VM

This script will check if user password expires in 1,3 or 7 days and if yes, it will send email to user


First, encrypt password and store it in file

$password = "somepass"
$secureStringPwd = $password | ConvertTo-SecureString -AsPlainText -Force
$secureStringText = $secureStringPwd | ConvertFrom-SecureString
Set-Content "C:\temp\ExportedPassword.txt" $secureStringText


$mailuser = ""

$pwdmail = Get-Content "C:\temp\ExportedPassword.txt"
$securemailPwd = $pwdmail | ConvertTo-SecureString

$EmailCreds = New-Object System.Management.Automation.PSCredential -ArgumentList $mailuser, $securemailPwd

$from = ""

# OU to search 

$path = "CN=Users,DC=example,DC=com"

$users = Get-ADUser -SearchBase $path -filter {Enabled -eq $True -and PasswordNeverExpires -eq $False -and PasswordLastSet -gt 0} `
-Properties "Name", "EmailAddress", "msDS-UserPasswordExpiryTimeComputed" | Select-Object -Property "Name", "EmailAddress", `
@{Name = "PasswordExpiry"; Expression = {[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed").tolongdatestring() }}

# Days remaining until password expiration
$WarningDays = 1,3,7

# Get current day
$today = (Get-Date).ToLongDateString()
try {
foreach ($user in $users)
 foreach ($WarnDay in $WarningDays){
 if ($user.PasswordExpiry -eq (get-date).adddays($WarnDay).ToLongDateString()) 
  # Calculate days beteween today and date when password will expire
  $ts = New-TimeSpan -Start $today -End $user.PasswordExpiry
  $days = $ts.Days
  $subject = "Password expiration notification - " + $user.Name
  $body = "Dear " + $ + ",`nYour Password will expire in " + $days + " days"
  Send-MailMessage -to $user.EmailAddress -from $from -Subject $subject -Body $body -BodyAsHtml -SmtpServer -UseSsl -Credential $EmailCreds -Port 587

catch {