Category Archives: MS Scripting

Add-VMNetworkAdapterExtendedAcl – allow only specific traffic to a VM and allow all outgoing traffic from a VM on Windows server 2016 – Hyper-V

Block all trafic to a VM:
Add-VMNetworkAdapterExtendedAcl –VMName “vm01” –Action “Deny” –Direction “Inbound” –Weight 10
Allow (for example) TCP 80 (HTTP) and TCP 443 (HTTPS) to a VM:
Add-VMNetworkAdapterExtendedAcl –VMName “vm01” –Action “Allow” –Direction “Inbound” –LocalPort 80 –Protocol “TCP” –Weight 11
Add-VMNetworkAdapterExtendedAcl –VMName “vm01” –Action “Allow” –Direction “Inbound” –LocalPort 443 –Protocol “TCP” –Weight 12
 
Allow any TCP and UDP from VM to ANY port and ANY address:
Add-VMNetworkAdapterExtendedAcl -VMName “vm01” -Action Allow -Direction Outbound -RemotePort Any -Protocol tcp -Weight 100 -IdleSessionTimeout 3600 -Stateful $True
Add-VMNetworkAdapterExtendedAcl -VMName “vm01” -Action Allow -Direction Outbound -RemotePort Any -Protocol udp -Weight 101 -IdleSessionTimeout 3600 -Stateful $True
 
Want to start over? Remove all ACLs:
Get-VMNetworkAdapterExtendedAcl -VMName “vm01” | Remove-VMNetworkAdapterExtendedAcl

Import and set TSGateway / RDGateway certificate with Powershell

As I noted in my previous article Let’s Encrypt started to issue wildcard certificates – and now for me it is a right time to automate the whole process of renewal and binding – and I am using Let’s Encrypt certificates also for my RD Gateway servers (some of them stand-alone without other TS/RD roles).

So how to get from PFX certificate “package” (before retrived from Let’s Encrypt) to a fully functional RDGateway?

Be careful with providing password for certificate import – Inserting passwords into scripts is not a good idea! – here I have inserted it in souch way just for an example:

$pass = “passw0rdforimport” | ConvertTo-SecureString -AsPlainText -Force

Then we need to import certificate in LocalMachine certificate store and save its Thumbprint into a variable $Thumbprint that we will use later to bind it to TS/RDGateway

$Thumbprint = Import-PfxCertificate -FilePath C:\lets\certificate_combined.pfx -Password $pass -CertStoreLocation Cert:\LocalMachine\My | select -ExpandProperty Thumbprint

Next we need to create CertHash that will be inserted in RDGateway settings

$Cert = Get-Item -Path Cert:\LocalMachine\My\$Thumbprint
$CertHash = $Cert.GetCertHash()

As we have our CertHash we can set the setting for TS/RDGateway

Get-CimInstance -Namespace root/CIMV2/TerminalServices -ClassName Win32_TSGatewayServerSettings | Invoke-CimMethod -MethodName SetCertificate -Arguments @{CertHash = $CertHash}

To apply new settings we need to restart TS/RDGateway service

Restart-Service -Name TSGateway -Force

 

How to change TXT record value on Micorosft DNS server using Powershell

As Let’s Encrypt anounced wildcard certificates I just wanted to make my life easier with automating the process of renewal and inserting values in TXT records to prove domain identity.

I am running all my DNS zones on Microsoft Windows server 2016 with DNS role installed where I will need to modify TXT record value every (little less) than three months to renew my *.domain.xyz cerificate. So how can we do it in Powershell just by modifing the existing value.

First time you will probably need to create the record by using:
Add-DnsServerResourceRecord

Add-DnsServerResourceRecord -Txt -Name _acme-challenge -DescriptiveText “SomeTextThatYouReceiveFromLet’sEncryptACME2Process” -ZoneName mydomain.xyz -TimeToLive 00:00:10

*I am keeping TTL very low here just in case you will need to repeat the process to expire soon (in 10 seconds).

Later on you will need just to modify the value of TXT record _acme-challenge
We have here a new cmdlet to the rescue: Set-DnsServerResourceRecord but it can not be simply used just to modify the value – you need to use two fill two parameter values called -OldInputObject (old record values) and -NewInputObject (new modified values).

Let’s take a look at the example:

$oldvalue = Get-DnsServerResourceRecord -ZoneName mydomain.xyz -RRType Txt -Name _acme-challenge
$newvalue = Get-DnsServerResourceRecord -ZoneName mydomain.xyz -RRType Txt -Name _acme-challenge
$newvalue.RecordData.DescriptiveText = “SomeNEWTextThatYouReceiveFromLet’sEncryptACME2Process”
Set-DnsServerResourceRecord -ZoneName mydomain.xyz -OldInputObject $oldvalue -NewInputObject $newvalue

What we did here is to declare two values where current values of the record are stored – $oldvalue and $newvalue.
Then I modified the $newvalue element called “DescriptiveText” that represents the text string of TXT record to some new data that I receive from ACME2 process when requesting Let’s Encrypt wildcard certificate.
At least I applied this new value to the record by using Set-DnsServerResourceRecord cmdlet and parameters.

 

Hyper-V virtual machine backup script…

Today my friend Marko Cepe sent me his VBS script that does great job to backup virtual machines that are running on Hyper-V.
This script does shut down virtual machine by sending shut down command to machine using integration services, then it waits virtual machine to enter stopped state, after that it does export of the machine and turns the machine back on.

Usage:

C:SKRIPTE> ExportVM.vbs VMName ExportDirectory

Example:

C:SKRIPTE> ExportVM.vbs TestVM X:BackupTestVM

Click, download and enjoy the script.

Comments appreciated…

Get IP address of virtual machines running on Hyper-V – FIXED!

Big thank you – goes to Max Trinidad my fellow MVP from Powershell group…
Here is errorless script – much better than mine! 🙂
Copa, paste and save as .ps1 – then run on your Hyper-V server and you will get IP’s of your virtual machines…

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned

## – Use Line below to list all your Virtualization Class
#get-wmiobject -namespace “root/virtualization” -list

## – Load filter (or function first)
filter Import-CimXml{

    $CimXml = [Xml]$_
    $CimObj = New-Object -TypeName System.Object
   
    foreach ($CimProperty in $CimXml.SelectNodes(“/INSTANCE/PROPERTY”)){
        if ($CimProperty.Name -eq “Name” -or $CimProperty.Name -eq “Data”){
            $CimObj | Add-Member -MemberType NoteProperty -Name $CimProperty.NAME -Value $CimProperty.VALUE
        }
    }
   
    $CimObj
}

## – Collect WMI Virtual information
$getWmiVirtual = Get-WmiObject -Namespace “rootvirtualization” -Query “Select * From Msvm_ComputerSystem” | sort-object elementname

## – Build your results from your collected objects
ForEach($v in $getWmiVirtual){
    $vm = $v.ElementName;
    $VmObj = Get-WmiObject -Namespace “rootvirtualization” -Query “Select * From Msvm_ComputerSystem Where ElementName=’$vm'”;
    $KvpObj = Get-WmiObject -Namespace “rootvirtualization” -Query “Associators of {$VmObj} Where AssocClass=Msvm_SystemDevice ResultClass=Msvm_KvpExchangeComponent”;
    if($KvpObj.GuestIntrinsicExchangeItems -ne $null){
        write-host $vm;
        $KvpObj.GuestIntrinsicExchangeItems | Import-CimXml | where {$_.NAME -match “NetworkAddressIPv4”} | ft;
    }
}

## – End of Script

Get IP address of virtual machines running on Hyper-V

I have been searching for an easy solution to somehow “scan” virtual machines and get their IP addresses becouse sometimes you need to find your virtual machines and it is more practical to somehow get a whole list of machines + IPs in stead of loging in from machne to machine and check IP… Well it can be done using Powershell… I have encountered an article but the problem is that here you need to put machine name on which you want to get data… I modified this script a bit so it looks like:

Get-WmiObject -Namespace rootvirtualization -Query “Select * From Msvm_ComputerSystem”| sort-object elementname | ForEach-Object {$vm = $_.Elementname
write-host $vm
filter Import-CimXml
{
    $CimXml = [Xml]$_
    $CimObj = New-Object -TypeName System.Object
    foreach ($CimProperty in $CimXml.SelectNodes(“/INSTANCE/PROPERTY”))
    {
if ($CimProperty.Name -eq “Name” -or $CimProperty.Name -eq “Data”)
{

         $CimObj | Add-Member -MemberType NoteProperty -Name $CimProperty.NAME -Value $CimProperty.VALUE

}
    }
    $CimObj
}
$VmObj = Get-WmiObject -Namespace rootvirtualization -Query “Select * From Msvm_ComputerSystem Where ElementName=’$vm'”
$KvpObj = Get-WmiObject -Namespace rootvirtualization -Query “Associators of {$VmObj} Where AssocClass=Msvm_SystemDevice ResultClass=Msvm_KvpExchangeComponent”
$KvpObj.GuestIntrinsicExchangeItems | Import-CimXml
} | where {$_.NAME -match “NetworkAddressIPv4”} | ft
read-host

So… Copy paste this script to an text file and save it as getip.ps1 and run it using powershell – it does need any other modules you should only run it on Windows Server where you have Hyper-V role installed… (I do not remember but I think you should enable execution policy for ps1 scripts… If you have truble executing your ps1 check here…)

By the way… This script has an error first virtual machine name will not fit in table (I do not know why 🙂 ) and you will get an error when this script will try to analyze your Hyper-V host machine… I do not know how to solve this two errors if someone out there solves it please provide feedback. 🙂 Thank you!

SBS 2011 – Import PST in Exhange 2011

To enable import and export of mailboxes on SBS 2011 you need to:

Go to Windows SBS console and create a security group – that shuld be universal (by default) for example: Mailbox management

Add administrator / admin account to the group

Then you need to enable “import / export” feature on members of this group. To do that you need to open Exchange Management Shell (Powershell with Exchange 2010 modules) as administrator and write:

New-ManagementRoleAssignment -Name “Import Export Mailbox Admins” -SecurityGroup “Mailbox management” -Role “Mailbox Import Export”

After that you can folow my article to import or export mailboxes