Change MAC Address with PowerShell of a Wireless Adapter

As I mentioned in my post a week ago, I’m commuting each day and there is a 200MB Quota on the Wireless Network. Luckily it’s based on the MAC Address of the WiFi Card, so it’s quite easy to get another 200MB Quota if you want  😉

wifi1

Here is my small powershell script that automatically Releases the IP Address, set’s a new random MAC Address and Re-Connects to the SSID, all done in a second or two.
Yay! Another 200MB Quota to burn.

function random-mac {   
    $mac = "02"
    while ($mac.length -lt 12) 
	{ 
		$mac += "{0:X}" -f $(get-random -min 0 -max 16) 
	} 
		
    $Delimiter = "-"
		for ($i = 0 ; $i -le 10 ; $i += 2) 
		{ $newmac += $mac.substring($i,2) + $Delimiter }
		$setmac = $newmac.substring(0,$($newmac.length - $Delimiter.length)) 
 $setmac
}


function disconnect-wifi { 
    $CurrentSSID = (& netsh wlan show profiles | Select-String 'Current User Profile' | Foreach-Object {$_.ToString()}).replace("    Current User Profile : ","$null")
    Write-Host "Current WLAN SSID: $CurrentSSID"  -ForegroundColor Yellow

    $WIFI = Get-WmiObject -Class Win32_NetworkAdapterConfiguration | Where { $_.IpEnabled -eq $true -and $_.DhcpEnabled -eq $true}
    Write-Host "Releasing IP addresses:" ($WIFI.IPAddress | select -first 1)  -ForegroundColor Yellow 
    $WIFI.ReleaseDHCPLease() | out-Null 

    # Make sure the Release have happened, else it give it 2 sec extra. 
    $WIFI = Get-WmiObject -Class Win32_NetworkAdapterConfiguration | Where { $_.IpEnabled -eq $true -and $_.DhcpEnabled -eq $true} 
    if ($WIFI.DefaultIPGateway -ne $Null) { 
    Write-Output "Release of IP Address had not completed, waiting 1 Seconds" 
    sleep -Seconds 2
    }

    Write-Host "Disconnecting from WiFi" -ForegroundColor Yellow 
    & netsh wlan disconnect | Out-Null
} 


function new-wifimac ($wifiadapter, $ssid, $newmac){ 

#    Write-Output "Wifi AdapterName: $wifiadapter" 
#    Write-Output "SSID: $ssid" 
#    Write-Output "New MAC Address to set: $newmac" 

    $oldmac = (Get-NetAdapter -Name $wifiadapter).MACAddress 
    Write-Output "OLD MAC Address: $oldmac" 

    if ($oldmac -like $newmac) {
        Write-Host "Old MAC and New MAC are identical, generating a new MAC Address" -ForegroundColor Red
        $newmac = random-mac
        Write-Output "New MAC Address to set: $newmac" 
        }

    Get-NetAdapter -Name $wifiadapter | Set-NetAdapter -MACAddress $newmac -Confirm:$false
    Get-NetAdapter -Name $wifiadapter | Disable-NetAdapter -Confirm:$false
    Get-NetAdapter -Name $wifiadapter | Enable-NetAdapter -Confirm:$false
    $currentmac = (Get-NetAdapter -Name $wifiadapter).MACAddress 
    Write-Output "NEW MAC Address: $currentmac" 

    Write-Host "Connecting to SSID: $ssid" -ForegroundColor Yellow 
    & netsh wlan connect name=$ssid ssid=$ssid

    $NoIP = 0
    Do { 
        $WIFI = Get-WmiObject -Class Win32_NetworkAdapterConfiguration | Where { $_.IpEnabled -eq $true -and $_.DhcpEnabled -eq $true}
        
        if ($WIFI.DefaultIPGateway -ne $null) { 
            $NoIP = 5
        }
        else {
            sleep -Seconds 2 
            Write-Host "Waiting for IP Address" 
            $NoIP += 1
        }
    } While ($NoIP -lt 5) 
    Write-Host "New IP addresses" ($WIFI.IPAddress | select -first 1)  -ForegroundColor Yellow 
}


function test-wifi ($probe){ 
    if (Test-NetConnection -ComputerName $probe -CommonTCPPort HTTP -InformationLevel Quiet) { 
        $result = "Working" 
    } 
    else { 
        $result = "NotWorking" 
    }
$result 
}


# Specify $SSID manually 
# $ssid = 'SSID-to-Connect-to' 
# 
# Or use the currently used SSID to reconnect to. 
$ssid = (& netsh wlan show interfaces | Select-String ' SSID ' | Foreach-Object {$_.ToString()}).replace("    SSID                   : ","$null")

# Specify WLAN Adapter Name Manually 
# $wifiadapter = 'vEthernet (External Wi-Fi)'
# 
# Or Try to identify the Wi-Fi Adapter 
$wifiadapter = (Get-NetAdapter | where Status -EQ "Up" | where MediaType -EQ "802.3" | where MacAddress -EQ (Get-WmiObject -Class Win32_NetworkAdapterConfiguration | Where { $_.IpEnabled -eq $true -and $_.DhcpEnabled -eq $true} | select *).MACAddress.replace(":","-")).Name

# Specify a MAC Address manually
# $newmac = "02-F4-D7-B2-FE-D8"
#
# Or generate a new Random MAC Address
$newmac = random-mac

disconnect-wifi
new-wifimac -wifiadapter $wifiadapter -ssid $ssid -newmac $newmac 
test-wifi -probe www.msftncsi.com

 

I’m using a Window 10 client with Hyper-V, and I’ve created a Virtual NIC for the WiFi adapter, that’s why it’s called ‘vEthernet (External Wi-Fi)’.  But you should be able to use the script with a normal WiFi Adapter too.

I’m using a Virtual WiFi Adapter, to be able to give my Virtual Machines access to internet also when I’m without a LAN.

Here is the script for creating a Virtual WiFi NIC;

Get-WindowsOptionalFeature -Online -FeatureName *hyper-v*all | Enable-WindowsOptionalFeature –Online -NoRestart -Verbose

Get-NetAdapter -Name "Wi-Fi" | New-VMSwitch -Name "Uplink Switch WiFi" -Verbose -AllowManagementOS:$false -MinimumBandwidthMode Weight -ComputerName $ENV:COMPUTERNAME
sleep -Seconds 5
Add-VMNetworkAdapter -ManagementOS -SwitchName "Uplink Switch WiFi" -Name "External Wi-Fi" -verbose -ComputerName $ENV:COMPUTERNAME
Set-VMnetworkAdapter -ManagementOS -Name "External Wi-Fi" -MinimumBandwidthWeight 20 -verbose -ComputerName $ENV:COMPUTERNAME

 

 

Block a Service (BITS) when on Wireless and specific Subnet

I’m commuting by train each day, working. The train has a free wireless network, but it’s limited to 200MB traffic, and is then reduced to snail speed. Luckily, it’s restricted by MAC-Address so it’s quite easy to get another 200MB when you run out 😉
Though, yesterday, I ran out of my 200MB quota in less than 7 minutes, which made me confused. A quick check confirmed what I suspected. Yepp, a new build of Windows 10 – fast ring is being downloaded and eating my quota.

Quick solution; create a Windows Firewall rule that blocks BITS from downloading stuff when on Wireless and using the trains subnet.

fw1

Here is the PowerShell syntax to create a similar rule.

# Block any inbound traffic from Service X on Wireless Network when using SubNet Y 
$Service = "BITS"
$SubNet = "10.101.0.0/16" 
New-NetFirewallRule -Name "Block $Service when on $SubNet / $Adapter" -DisplayName "Block $Service when on $SubNet" -Enabled True -Direction Inbound -Action Block -LocalAddress "$SubNet" -Service "$Service" -InterfaceType Wireless -Profile Public 

Yay! No more problems with eating the quota while on the train.

Should the image contain hotfixes or not?

One more post in my WSUS/Hotfix series of blogposts. I’ve been asked a couple of times how we approve Hotfixes and if we include them in the images.

I’ve made an Autoapproval Rule where we approve all Hotfixes automatically to the various Computer Groups with a Deadline, like this.

wsus16

And this is how the details looks like;

wsus17

First of all, any server that could cause problems if it automatically rebooted doesn’t have a Deadline, thats servers like Hyper-V Hosts and SOFS Nodes. Those servers are managed by SCVMM’s (System Center Virtual Machine Manager) Patch Management. VMM has a feature to put a cluser node in maintenance mode, automatically drain the node of VM’s, patch it, and then bring the node back online again before it takes the next node.  So we handle all patching of clustered servers from SCVMM. While we let the WSUS Client handle all other servers. We might add SCCM to the mix some day and let it handle all of the servers, but as most of our customers don’t want to run SCCM to manage their Fabric, this is the way we do it now.

By putting a deadline, we know the hotfix will be installed sooner or later. And if there is a Patch Tuesday before that date, it will also install the hotfixes at the same time.

Notice that the hotfix is NOT approved for All Computers and NOT for Unassigned Computers. How come?

When we build a VM image for any OS, it’s done automatically through MDT. Those VM’s are ending up in Unassigned Computers as they don’t have a role yet and we don’t want any Hotfixes in the images. Of course, if there is a mandatory hotfix whish is needed to make the image or deploy it, that one will be included!

The reasons we don’t want any hotfixes in an image is quite simple if you think about it. There are two main reasons really.
The first one is that if we make an image in august, which contains hotfixes. When we deploy that image 3 months later, there is a big chance that the hotfix we had in the image is replaced by a proper update from Microsoft so there was no use for the hotfix in the first place.
Second, when we create an image, we don’t add Clustering, Hyper-V and other roles and features to the image, right? So Windows will then only install the hotfixes for the core OS. And when the image is later deployed and someone adds the Hyper-V Role, it would install hotfixes for that role then. So the server wouldn’t be fully patched anyway so adding 5 or 15 hotfixes automatically after deployment doesn’t really make much of a difference.
Third, a minor reason is also that we normally use the same images for Fabric, Workload and Tenants and we like to keep them quite generic.

Here is a great blogpost about making reference images from my colleague Mikael Nystrom.

 

Semi-Automatic Hotfix import into WSUS

One of my blogreaders, Andreas Fjellner, came up with a way to make the import of hotfixes a bit faster than copy and paste.

You can download a XML file with all the Hotfixes I’ve got imported so you don’t have to do a findstr or excel filtering from the previous blogpost, the XML file contains the same list as shown here List of Private Cloud related Hotfixes – 2016-02-03

Download: XML File (notice the Download button at the top so you don’t have to copy and paste). Save the file as c:\temp\details.xml on your WSUS Server and then run this script;

$url = (Import-Clixml C:\temp\details.xml).MUUri  

$pauseOn = "21","41","61","81","101","121","141"
 
$i = 0
foreach ($u in $url) {
$i++
If ($i -in $pauseOn) {
    Write-Host "Import hotfixes before continue, then press Y"
    $continue = Read-Host
    If ($continue -ne "Y") {exit}
    }
    $i
    & 'C:\Program Files\Internet Explorer\iexplore.exe' $u
} 
 

It will spawn one internet explorer for each Hotfix with the correct URL. Just click ADD to basket. Close the IE Window and pick the next window.
When you are done with the first batch of 20 hotfixes, use the “Import updates” link as described here: Importing Hotfixes and Drivers directly into WSUS and you will now be able to import all hotfixes into your WSUS. And now press Y in the powershell window to take the next batch of hotfixes. Repeat until done.

Another way is to use AutoIT to make a script that moves the mouse and clicks on the right place doing the import semi-automatic, as another blogreader pointed out. There is always a way!

Importing Hotfixes and Drivers directly into WSUS

I got a comment on my previous blogpost.

Could you please clarify the import bit with paste:ing the uri into Wsus IE.
If you paste the Uri into the address field it wants do dowload the update and not import it.

You are right, I was very unclear about that and should have explained it, thanks for asking Patrik.

This process can be used to import anything from the Microsoft Update Catalog, including Drivers and public Hotfixes.

Start by opening your WSUS Console, and click on “Import Updates”.
It has to be done that way to get the “import” option, else you will only be able to download the files.

wsus10

 

An normal Internet Explorer will now open. If this is the first time you are doing this, you will be prompted to approve an activex component and you may have to trust the updates website too.

wsus11

 

You can either search for hotfixes (or drivers) by their name, or just paste the MUUri that’s listed on each hotfix in my post here: http://www.isolation.se/list-of-private-cloud-related-hotfixes-2016-02-03/  And then click on Add to put the hotfixes in your basket.

wsus12

 

When you have added a couple of hotfixes to the basket click on “View Basket”. My experience is that adding too many hotfixes will make the Microsoft Update site timeout and be unresponsive. So I usually import the hotfixes or drivers in batches of 20-30 at the same time.

wsus13

Notice in the picture above, how there is no Import but just the normal Download button. If that happens, just switch back to the Windows Update Admin console, and click import updates again. A new tab will open in IE, it will remember all your items in the basket and a Import Directly into Windows Server Update Services checkbox exists now!

wsus14

Just import the hotfixes to WSUS that way, and approve them manually or make an Auto Approval Rule. Done!

The bad part, is as I mentioned in a previous blogpost, that you have to copy and paste each hotfix url into IE. I’ve not managed to figure out a way to script the import as it’s a ActiveX component doing all the work.

 

Live (VSM) migration fails with mirror operation failed and access is denied error

When doing a Live Migration from SCVMM (System Center Virtual Machine Manager) with VSM, moving a Virtual Machine from one Cluster to another Cluster and at the same time also to a new Storage Location, you are getting an error message similar to this:

Error (12700)
VMM cannot complete the host operation on the HOST07.FABRIC.DOMAIN.COM server because of the error: Virtual machine migration operation for 'markustest01' failed at migration source 'HOST07'. (Virtual machine ID FAA0957A-4AF9-4B84-8AE9-2E9BC56CA9A6)

Migration did not succeed. Could not start mirror operation for the VHD file '\\FASOFSL02.FABRIC.DOMAIN.COM\CSV02\markustest01-1\FAS2012R2-001G2.vhdx' to '\\FASOFS01.FABRIC.DOMAIN.COM\vDisk03\markustest01-6\FAS2012R2-001G2.vhdx': 'General access denied error'('0x80070005').
Unknown error (0x8001)

Recommended Action
Resolve the host issue and then try the operation again.

The strange thing is that there is a destination folder in the new location, it’s just does not copy content to that folder and aborts with the Access Denied error. But If you shutdown the VM first, so it’ s just a migration over the Network, it works!

The solution is to give the SOURCE Cluster Write Access on the DESTINATION Storage. When you do a VSM Migration, the destination Hyper-V host, creates the Directory on the SOFS Node, but it’s the Hyper-V Host that owns the VM that copies the VHD’s files to the destination storage. And as the current owner, by default does not have access to write there, it will fail. One could think that VMM should grant permissions to a host when VMM knows that the host needs to write in the location?

Maybe it’s fixed in the next version, but until then, there are two ways to do this.
Solution 1) In VMM add the Destination SOFS Shares as Storage on the Source VM Hosts like this. That will make VMM add the VM Hosts with Modify Permissions in the SOFS Shares so it can write there.

sofs2

This works quite fine, if the Hyper-V Clusters and all Storage is located in roughly the same location. But if you have one compute cluster with storage in one location, and another compute cluster with storage in another location. There is then a risk that you may be running VM’s cross the WAN link.

Solution 2) This is the one we used. By not using VMM to grant permissions to the shares, but rather do it manually we achieve the same solution as above but with the added benefit that a new VM will always be provisioned on the local storage and there is no (or a lot less) risk of running a VM cross the WAN link. Yes, it’s still technically possible to do it, but no one will by accident provision a VM that uses storage in the other datacenter.

You can either add each node manually, so we have created a “Domain Servers Hyper-V Hosts” security Group in AD where we add ALL Hyper-V hosts to during deployment. And then added that group to the Share and NTFS Permissions. All Hyper-V hosts will then automatically have write access to all locations they may need.

I wrote these two short scripts to query the VMM Database for the available SOFS Nodes and use powershell to grant permissions to the share, and to NTFS.

As all our SOFS Shares were called vDiskXX or CSVXX (where XX is a number) I just used a vDisk* and CSV* to do the change on all those shares. You might have to modify it a little to suit your name standard.

# Grant SOFS FileShare permissions to group: Domain Server Hyper-V Hosts
$group = (Get-ADGroup "Domain Server Hyper-V Hosts").Name
$servers = ((Get-SCStorageFileServer | select StorageNodes).storageNodes).Name
foreach ($srv in $servers) { 
  Get-SmbShare -CimSession $SRV -Name vDisk* | Grant-SmbShareAccess -AccountName $group -AccessRight Full -Force
  Get-SmbShare -CimSession $SRV -Name csv* | Grant-SmbShareAccess -AccountName $group -AccessRight Full -Force
}

# Grant NTFS permissions to group: Domain Server Hyper-V Hosts
$FileShares = Get-SCStorageFileShare 
foreach ($share in $FileShares.SharePath) {
 $acl = get-acl $share
 $group = (Get-ADGroup "Domain Server Hyper-V Hosts").Name

 $permission = "$env:USERDNSDOMAIN\$group","FullControl", "ContainerInherit, ObjectInherit", "None", "Allow" 
 $accessRule = new-object System.Security.AccessControl.FileSystemAccessRule $permission

 $acl.SetAccessRule($accessRule)
 $acl | Set-Acl $share -Verbose
}

Updated Script (2016-02-04):
I got a report that the script was getting an error on some servers, which I managed to reproduce. Here is an alternative version where it will connect to the server and execute the ACL change locally via invoke-command. It’s also only changing permissions on Continuously Available (SOFS) shares.

$FileShares = Get-SCStorageFileShare | where StorageClassification -notlike "Library" 

foreach ($share in $FileShares) {
  $SMBServer = $share.StorageFileServer.StorageNodes[0].Name
  $SOFSCluser = $share.StorageFileServer.Name

  Write-Output "Connecting to Node: $SMBServer for SOFS Cluster: $SOFSCluser"
  Invoke-Command -ComputerName $SMBServer -Verbose -ScriptBlock { 

  # Change to the right Group Name here 
  $Group = "FABRIC\Domain Server Hyper-V Hosts"
  $SOFSShares = Get-SmbShare | where { $_.ContinuouslyAvailable -eq "True"}
  $SOFSShares | Grant-SmbShareAccess -AccountName $Group -AccessRight Full -Force

  foreach ($SOFSShare in $SOFSShares) {
    $ShareDir = $SOFSShare.Path
    $acl = (Get-Item $ShareDir).GetAccessControl('Access')
    
    $permission = "$Group","FullControl", "ContainerInherit, ObjectInherit", "None", "Allow" 
    $accessRule = new-object System.Security.AccessControl.FileSystemAccessRule $permission

    $acl.SetAccessRule($accessRule)
    Write-Output "Set ACL on: $ShareDir" 

    $acl | Set-Acl $ShareDir
    }
  }  
}

 

 

List of Private Cloud related Hotfixes – 2016-02-03

I’ve posted my list of resources for finding Hotfixes previously here.  And this is a list of hotfixes we’ve imported in our WSUS server for our and our customers Private Clouds.
I usually want to install a hotfix to avoid getting a known problem, than try to find a solution to a problem after it has already happened and affected the users and customers.

wsus3

I’ve used the script I posted here to make the list. I’m sorry for the format below, but there is no good way to extract the info from WSUS and as I don’t really know if anyone is interested in this besides myself, I won’t spend hours on fixing a nice output right now or I would never get this blogpost published.  Sorry!

I’m using the MUUri to paste into the WSUS IE to search and locate the hotfixes fast, instead of manually search for each. There is unfortunately no way to script the import according to Microsoft PM’s, so it has to be done manually. Sigh…

Continue reading List of Private Cloud related Hotfixes – 2016-02-03

Export information from WSUS about Hotfixes or Updates

I want to export information about all our Hotfixes in our WSUS Server, to share with the community as it’s sometimes hard to find up to date info of which hotfixes to apply in an environment.

Here is a quick and dirty script. No, scratch that, it’s not quick in any way but very dirty. The problem is that the WSUS Database does not contain the Description or Title of a Hotfix, so it’s not possible to export that info. Thus, I’ve to use a scripted Internet Explorer, to navigate to the URL of each Hotfix and grab the Title. Which makes the process veeeeeeery slow but I’ve been unable to come up with any better solution than that.

This is how the output looks like:

wsus2

And here is the full script, I will be really grateful if you share any changes you do as I’m sure there is a lot of ways to improve this script.

# Load WSUS Stuff 
[reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration") | out-null 
if (!$wsus) { 
  $wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::GetUpdateServer(); 
} 
 
$updateScope = new-object Microsoft.UpdateServices.Administration.UpdateScope; 
$updateScope.UpdateApprovalActions = [Microsoft.UpdateServices.Administration.UpdateApprovalActions]::Install
$computerScope = new-object Microsoft.UpdateServices.Administration.ComputerTargetScope;
 
[DateTime]::UtcNow.ToShortDateString() 


Function Get-Title($Web) {
        if ($Web -ne "https://go.microsoft.com/fwlink/?LinkId=133041")
            {
				$ie = new-object -com internetexplorer.application
				$ie.navigate($Web)
				while ($ie.busy -eq $true) { Start-Sleep -Milliseconds 600 }
				$BaseResponse = $ie.LocationURL
		
				if ($BaseResponse -ne $Web) { $Title = "Site may no longer be available. Site redirection occurred - new target $BaseResponse." }
				else
				{
					while (($ie.LocationName -eq "Microsoft Support") -or ($ie.LocationName -eq $Web)) 
                        { 
                            $ie.refresh();
                            while ($ie.busy -eq $true) { Start-Sleep -Milliseconds 600 }
                        }
					$Title = $ie.LocationName.tostring()
                    $ie.Quit()					
				}
			}
	Else
	{
		$Title = "Invalid URL - Original KB was for IE 9.0..."
	}
	start-sleep -Seconds 1
        return $Title.ToString()
    }#end function Get-Title


Function Get-KB($HotfixList){  
  $TestList = @()
  foreach ($Hotfix in $HotfixList) {  
  $KB = $null
  write-Host "Processing Hotfix $Hotfix Please Wait."
  $KB = $wsus.GetUpdates($updateScope) | where { ( $_.KnowledgebaseArticles -match "$Hotfix" )}
  if ($KB -ne $null) { 
    $summary = $KB.GetSummary($computerscope); 
    $neededCount = ($summary.InstalledPendingRebootCount + $summary.NotInstalledCount)
    $CreationDate = $KB.CreationDate 
    $InstalledCount = $Summary.InstalledCount.ToString()
    $MUUri = "http://catalog.update.microsoft.com/v7/site/Search.aspx?q="+$KB.KnowledgebaseArticles
    $KBUri = $KB.AdditionalInformationUrls -replace 'http:','https:' -replace 'microsoft.com/kb/','microsoft.com/en-us/kb/'
    $KBTitle =  Get-Title ($KB.AdditionalInformationUrls -replace "http:", "https:" -replace "microsoft.com/kb/", "microsoft.com/en-us/kb/")


    $KBsummary = New-Object -TypeName System.Object
    Add-Member -InputObject $KBsummary -MemberType NoteProperty -Name KB -Value $Hotfix
    Add-Member -InputObject $KBsummary -MemberType NoteProperty -Name KBTitle -Value $KBTitle
    Add-Member -InputObject $KBsummary -MemberType NoteProperty -Name KBUri -Value "$KBUri" 
    Add-Member -InputObject $KBsummary -MemberType NoteProperty -Name MUUri -Value $MUUri
    Add-Member -InputObject $KBsummary -MemberType NoteProperty -Name ReleaseDate -Value $CreationDate.ToShortDateString()
    Add-Member -InputObject $KBsummary -MemberType NoteProperty -Name ProductTitles -Value $KB.ProductTitles 
    Add-Member -InputObject $KBsummary -MemberType NoteProperty -Name ProductFamilyTitles -Value $KB.ProductFamilyTitles  
    Add-Member -InputObject $KBsummary -MemberType NoteProperty -Name UnknownCount -Value $summary.UnknownCount
    Add-Member -InputObject $KBsummary -MemberType NoteProperty -Name NotApplicableCount -Value $summary.NotApplicableCount
    Add-Member -InputObject $KBsummary -MemberType NoteProperty -Name DownloadedCount -Value $summary.DownloadedCount
    Add-Member -InputObject $KBsummary -MemberType NoteProperty -Name InstalledCount -Value $summary.InstalledCount
    Add-Member -InputObject $KBsummary -MemberType NoteProperty -Name InstalledPendingRebootCount -Value $summary.InstalledPendingRebootCount
    Add-Member -InputObject $KBsummary -MemberType NoteProperty -Name FailedCount -Value $summary.FailedCount
    $TestList += $KBsummary
    }
  else{
  Write-Host "$Hotfix not found"
  }
 }
  return $TestList
}


$allhotfixes = $wsus.GetUpdates($updateScope) | where { ( $_.UpdateClassificationTitle -match "Hotfix" ) -and ( $_.IsDeclined -eq $false ) -and ( $_.IsLatestRevision -eq $true) -and ( $_.IsSuperseded -eq $false) -and ( $_.ProductTitles -like "*2012 R2*") } 
$Details = Get-KB $allhotfixes.KnowledgebaseArticles

$Details | Export-Clixml -Path c:\temp\details.xml 
$Details 


 

Geek Week – Building Datacenter and Private Cloud

Yours truly and @mikael_nystrom  are teaching a 5 day training called “Geek Week – Building Datacenter and Private Cloud“.
It’s a quite cool concept, where we are always at least 2 teachers (Mike and me, and sometimes members from our team) with a lot of real-life experience, teaching students how to build a Software Defined Private Cloud/Datacenter on Microsoft Technology in just 5 days. We have been doing this training about 4 times so far and each time got top score !

The training is covering things like; Software Defined Storage, Networking Compute, Bare Metal Deployment, SCVMM, SCOM, SCOR, Powershell(!), Azure Pack, Backup/Restore, Operational Insight, AD Design for your Fabric, GPO’s, Patch Management and a lot more!

So instead of just learning one product, you will learn the full stack, the concept, how to design, build and of course manage it.

We’ve made a short promo video with details here:

You will of course also keep the Lab Server and all the scripts!
We are both staying at the same hotel as the students, so you will have – almost 24h access to our knowledge, experience and brains during breakfast, daytime and in the bar in the evenings, Sunday-Friday.

We have delivered the training only in Sweden so far, due to the huge hardware requirements,  but have had participants from several other countries, including students from US (and doing the training in English than).

Unfortunately, for you but great for us, the next training in October, is SOLD OUT!
The next opportunity will probably be in February or March in Sweden, so talk to your manager and sign up while there are seats left.
http://www.labcenter.se/Labs#!lab=Geek_Week_-_Building_Datacenter_and_Private_Cloud  (Unfortunately only in Swedish)

Send me a mail if you have any questions: markus . lassfolk at truesec . se

Working with Virtual NIC’s in Windows

At times when I’m for example at a customer and need to connect my Laptop to different VLAN’s it’s really nice to add new virtual Network Cards (vNIC’s) on the fly, and be connected to multiple networks at the same time. vnics

By transforming the Network Cards in your computer, into a virtual switch, and then add Virtual Network Cards connected to that switch, it’s possible to do a bit of network magic.

Here is a part of the script that I run each time I reinstall my PC’s to create the vNIC’s that I need and use the most. The script is also installing the software I need and doing some other minor changes (always a work in progress).

Pre-Requisits: Hyper-V Role installed

# Create a Switch for Ethernet Network 
Get-NetAdapter -Name "Ethernet" | New-VMSwitch -Name "Uplink Switch" -Verbose -AllowManagementOS:$false -MinimumBandwidthMode Weight -ComputerName $ENV:COMPUTERNAME
Add-VMNetworkAdapter -ManagementOS -SwitchName "Uplink Switch" -Name "External LAN" -verbose -ComputerName $ENV:COMPUTERNAME
Set-VMnetworkAdapter -ManagementOS -Name "External LAN" -MinimumBandwidthWeight 20 -verbose -ComputerName $ENV:COMPUTERNAME 

# Create a Switch for WiFi Network 
Get-NetAdapter -Name "Wi-Fi" | New-VMSwitch -Name "Uplink Switch WiFi" -Verbose -AllowManagementOS:$false -MinimumBandwidthMode Weight -ComputerName $ENV:COMPUTERNAME
Add-VMNetworkAdapter -ManagementOS -SwitchName "Uplink Switch WiFi" -Name "External WLAN" -verbose -ComputerName $ENV:COMPUTERNAME
Set-VMnetworkAdapter -ManagementOS -Name "External WLAN" -MinimumBandwidthWeight 20 -verbose -ComputerName $ENV:COMPUTERNAME

# Add a vNIC for VLAN11 on Physical Network Card
Add-VMNetworkAdapter -ManagementOS -SwitchName "Uplink Switch" -Name "VLAN11" -Verbose -ComputerName $ENV:COMPUTERNAME
Set-VMNetworkAdapterVlan -ManagementOS -Access -VlanId 11 -VMNetworkAdapterName "VLAN11" -Verbose -ComputerName $ENV:COMPUTERNAME
Set-VMnetworkAdapter -ManagementOS -Name "VLAN11" -MinimumBandwidthWeight 10 -verbose -ComputerName $ENV:COMPUTERNAME

# Add a vNIC for VLAN800 on Physical Network Card
Add-VMNetworkAdapter -ManagementOS -SwitchName "Uplink Switch" -Name "VLAN800" -Verbose -ComputerName $ENV:COMPUTERNAME
Set-VMNetworkAdapterVlan -ManagementOS -Access -VlanId 800 -VMNetworkAdapterName "VLAN800" -Verbose -ComputerName $ENV:COMPUTERNAME
Set-VMnetworkAdapter -ManagementOS -Name "VLAN800" -MinimumBandwidthWeight 10 -verbose -ComputerName $ENV:COMPUTERNAME

Thanks to my friend and colleague Mikael Nyström who showed me this a few years ago.