Category Archives: Blog

Be God

If you want to feel like God in your own Windows 8 universe, try this little powerShell one-liner:

New-Item -ItemType Directory -Path "$env:USERPROFILE\Desktop\GodMode.{ED7BA470-8E54-465E-825C-99712043E01C}"

This will add an ikon to your desktop similar to this one

God mode

God mode

In that folder you will find a collection of most Windows 8 settings. So now you can act like God in your Windows 8 universe.

Can we have “Latest” URLs for downloads, please!

Background

I spend much time hunting for the latest version of software packages. This is part of my job as a consultant. I’m frequently setting up test, demo and prototype environments. I do this in order to keep myself in synch with new technologies. And to help others learn and use new technology.

I write presentations, demos, blog posts, instructions, howtos etc.

The Problem

As the release cycles gets shorter and shorter it is becoming increasingly hard to write good instructions. For example, If I need to explain how to install the latest “Windows Management Framework” I will need a very specific URL. (As of this writing the latest I have found is the may preview. )

If I put this URL in a wiki or blogpost it will be obsolete very quickly (the previous release of the WMF 5 preview was in april) and so I will have to either updare my blogpost or trust the user to find the correct latest version.

If I omit the URL and instead write a general instruction such as “Search Google for ‘Windows management Framework Download’” the user of my documentaton can end up with any version at all as is shown from these to examples from Bing and Google.

Search-bing Search-Gogle
Bing result Google result

NB: See how the Google search returns the next to latest edition, there is no trace of the latest version of the Windows Management Framework may preview.

This makes it very likely that whoever is following my written instruction will not end up with the latest version of Windows Management Framework.

The Solution

The solution that I would like to propose is that Microsoft start using a download URL constructed as this

http://microsoft.com/download/<product>/latest

Using Windows Management Framework as an example:

http://microsoft.com/download/wmf5/latest

This URL would ensure that I get the latest release code, not the next best or whatever I find on Google, Bing, DuckDuckGo or wherever I am searching.

If I don’t want the bleeding edge I could use:

http://microsoft.com/download/wmf5/stable

If I needed a specific version te URL could be similar to:

http://microsoft.com/download/wmf5/2014-04-03

What this would require (I’m guessing now) is that somewhere within Microsoft a list of downloads would need to be mapped to the latest release code. The list of product names would need to be made into URL friendly shortnames (<product> in my example above). And the build processes for putting stuff on the Microsoft download sites would need to be adjusted so that it maps the “latest” to the most recently released piece of code.

I’m sure Microsoft have done more complex projects than this! Ler

So please Microsoft, give us more documetation friendly URLs!!!

Disclaimer

What I propose above is nothing new. Many open source projects already do this. A good example is WordPress. It’s simple to write instructions for a user to get the latest WordPress, the URL is:

https://wordpress.org/latest.zip

Let me know what you think! And even better, get this fixed Microsoft!

Installing Ubuntu 14.04 LTS as a Generation 2 Hyper-V guest

Since Microsoft release Windows Server 2012 R2 Hyper-V have had two different generations of virtual machines. The old “Generation 1” and the new “Generation 2”. Microsoft added generation 2 to get rid of the old stuff that really doesn’t make sense in a virtual world. And also to add new stuff. Generation 2 virtual machines provide the following new functionality:

  • PXE boot by using a standard network adapter
  • Boot from a SCSI virtual hard disk
  • Boot from aSCSI virtual DVD
  • Secure Boot (on by default)
  • UEFI firmware support

As can be expected all of these features worked fine straight away with Windows 8 (64-bit) and Windows Server 2012 or later. But they did not work well with Linux. Until now.

The fresh Ubuntu 14.04 LTS release works fine with and can be installed into a generation 2 virtual machine in Hyper-V. There is only one thing you need to know – Secure Boot has to be disabled. Hyper-V enables secure boot by default so if you just click through the wizard to create a VM it will not work. You have to disable Secure Boot.

Here’s the PowerShell way to check if Secure Boot is enable for your VMs:

Get-VM | Get-VMFirmware

To disable Secure Boot for a specific VM (‘TrustyTahr’) use this:

Get-VM -Name 'TrustyTahr' | Set-VMFirmware -EnableSecureBoot Off

Now you can install Ubuntu in a generation 2 Hyper-V machine. It just works. And even though I have not done any valid tests the gen 2 Ubuntu machine feels a lot snappier than on old one.

PowerShell loves enumerations

One of the things that make PowerShell oh-so-great is its tight integration with .NET Framework. As a simple example, in the framework there are many pre-define values, often stored as enumerated types. Enums are great because they allow us to define a set of values and then let the user (or program) choose among these values.

Another great thing with PowerShell is that it makes command arguments ‘pickable’ on the command line. So if I’m running a command and I am unsure of which arguments can be used I can simply press tab and I will se the first valid parameter value.
Let me show you the simple beauty of Enums together with PowerShell scripts.

function Get-SpecialFolderPath
{
  param ( [System.Environment+SpecialFolder]$SpecialFolder )
  return [System.Environment]::GetFolderPath($SpecialFolder)
}

This function takes one argument, the alias of a special folder, and returns the physical location of the special folder. The special folders that Windows knows about are define in the enumeration Environment.SpecialFolder. You can use the function like this:

Get-SpecialFolderPath -SpecialFolder Cookies
C:\Users\Joakim\AppData\Local\Microsoft\Windows\INetCookies

This in itself may not impress you (me neither:-)). But when you use this function toghether with your own function or other PowerShell cmdlets it becomes a great help for the user. Let’s say you want to quickly check what is in the users Cookie folder. How would you know where the cookies are stored? With this function you don’t, it is enough to type:

Get-SpecialFolderPath *tab*

As this is a static blogpost I can’t show you what happens when I press the <tab> key. but what does happen is that you will get the first value in the SpecialFolder enumeration, “Admintools”. Press tab again and you’ll get the second value which is “ApplicationData”. Another press of the tab key gies you “CDBurning” and so on.  You can of course avoid pressing tab many times by providing part of the name of the folder your are looking for:

Get-SpecialFolderPath coo *tab*

When you press tab this will expand to:

Get-SpecialFolderPath Cookies

A more relevant example: If you want to list all items on the users desktop you can combine Get-ChildItem with Get-SpecialFolder as this:

Get-ChildItem (Get-SpecialFolderPath Desktop)

This will give you a listing of all items in your dekstop folder. Again, the beauty is that you do not need to know the exact path to the Desktop folder.

Using enumerations to get input can really make your PowerShell scripts a lot easier to use and safer. So I hope you take some time to play around with using enumerations with your functions and cmdlets!

$env:HOME doesn’t work in PowerShell $PROFILE

Today I wanted to setup my PowerShell $PROFILE to make it easier to work with all the modules I learned about at the PowerShell Summit. I wanted to add an additional path to the environment variable $PSModulePath. Something that should be a picece of cake.

I store additional modules in the folder ‘Documents\WindowsPowerShell\Modules’ under my userdirectory (C:\Users\Joakim). So simply joining the path using Join-Path and add the result to $ENV:PSModulePath should do the trick:

$env:PSModulePath += ';'+ (Join-Path -Path ${env:HOME} -ChildPath 'Documents\WindowsPowerShell\Modules')

Unfortunately that didn’t work. And it confused me. Executing this on the PowerShell commandline worked fine, but when I put the line above in my $PROFILE it gave me this error:

Join-Path : Cannot bind argument to parameter 'Path' because it is null.
At C:\Users\Joakim\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1:3 char:44
+ $env:PSModulePath += ';'+ (Join-Path -Path ${env:HOME} -ChildPath 'Do ...
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Join-Path], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.JoinPathCommand

I understand what the error says and apparently the environment variable HOME is not instantiated when the $PROFILE is executed. This really confuses me. I already have the following line in my profile and it workes like a charm:

[System.Environment]::SetEnvironmentVariable('PATH',"C:\Users\Joakim\SkyDrive\Util;$env:PATH")

So environment variables are available when $PROFILE is executing… After a bit of frustration I changed from using

$env:HOME

to using

$env:USERPROFILE

and then it works!

So a word of advise if you want to find the users homedirectory when in the context of $PROFILE. Do not use $env:HOME

If anyone can explan when the HOME variable is instatiated vs the USERPROFILE… I’m listening 😉

Quick way to name your NICs in Windows Servers

If you, like me, manage many servers, it’s essential to name network adapters in a way that makes it easy to troubleshoot issues when they arise.

In complex networks with thousands of servers and all servers connected using multiple paths a consistent naming standard is very important!

PowerShell and the cmdlets available in Windows Server makes naming adapters a breeze. The servers we usualy deploy have built in four (4) port network adapters. We like to name the Windows NICs the same as is the default in Linux; eth0, eth1, etc.

In the following example we name the adapters eth0, eth1, eth2 and eth3 in Windows. The NIC with the lowest MAC address gets the name eth0 etc. (If you prefer to to start naming adapters from eth1 change the variable $NICs to 0):

 $NICs = -1
 Get-NetAdapter Etherne* | Sort-Object MacAddress | % { Rename-NetAdapter -InterfaceAlias $_.InterfaceAlias -NewName eth$NICs }

PowerShell really makes life easy 😉

Minimal CentOS 6.4 with Hyper-V

Now that CentOS includes the kernel drivers for Hyper-V it is very easy to setup a CentOS 6.4 based server in Hyper-V. Download the “minimal” ISO and create a new Hyper-V VM. Run through the installation and reboot.

What you will notice when logging in is that the eth0 NIC has not been started. This is normal and if you want to access the network with a DHCP assigned address simply start the interface:

ifup eth0

Now you should be able to access the network that your Hyper-V VM has access to.

Since you don’t wan’t to do this everytime you start your system you need to change a config file. The file to change is (provided your NIC is named eth0)

/etc/sysconfig/network-scripts/ifcfg-eth0

The contents of this file is something similar to this:

DEVICE=eth0
HWADDR=00:15:5D:01:7F:0C
TYPE=Ethernet
UUID=7042ad34-28c7-4b0e-96ab-3c69ee778901
ONBOOT=no
NM_CONTROLLED=yes
BOOTPROTO=dhcp

If you’re happy with getting your IP from the DHCP server, simply change the “ONBOOT=no” to “ONBOOT=yes”. Next time you reboot you will get your network straight away.

Keep It Simple Silly

This is a list I ran across on the Internet. I’ve kept it as a draft for some time but felt it is Worth sharing, so here it is:

Missing someone… Call!
Wanna meet up… Invite!
Wanna be understood… Explain!
Have a question… Ask!
Don’t like something… Say it
Like something… State it!
Want something… Ask for it!
Love someone… Tell them!

Nobody will know what is going on in your mind.

It’s better to express rather than to expect. You already have the NO, Take the risk of getting the YES
We just have one life!

Keep It Simple Silly

Enumerate UPNP devices

At home I have a Sonos system. It’s probably the best of any device that I have owned in terms of quality, usability and sheer happiness. The Sonos system has been working just fine for many years. It just works!

Recently I was fortunate enough to get a direct fiber into my house. Needless to say this triggered me to update my home network. Part of this upgrade was to install Ubiquiti long range access points for better performance and coverage as well as a new firewall. After this network upgrade Sonos system then started to behave strangely which brings me to the reason for this post!

I had to troubleshoot the Sonos system, a good start would be to see that all the devices were available and OK. A quick google search found a few PowerShell examples for how to use the UPnP.UPnPDeviceFinder COM object. Here’s one example that I found:

$finder = New-Object -ComObject UPnP.UPnPDeviceFinder;
$devices = $finder.FindByType("upnp:rootdevice", 0)
foreach($device in $devices)
{
    Write-Host ---------------------------------------------
    Write-Host Device Name: $device.FriendlyName
    Write-Host Unique Device Name: $device.UniqueDeviceName
    Write-Host Description: $device.Description
    Write-Host Model Name: $device.ModelName
    Write-Host Model Number: $device.ModelNumber
    Write-Host Serial Number: $device.SerialNumber
    Write-Host Manufacturer Name: $device.ManufacturerName
    Write-Host Manufacturer URL: $device.ManufacturerURL
    Write-Host Type: $device.Type
}

If you run this you get what you want, here’s a partial output:

---------------------------------------------
Device Name: BUBBA
Unique Device Name: uuid:4d696e69-444c-164e-6b41-101f743be078
Description: MiniDLNA on Debian
Model Name: Windows Media Connect compatible (MiniDLNA)
Model Number: 1
Serial Number: 12345678
Manufacturer Name: Justin Maggard
Manufacturer URL: http://www.debian.org/
Type: urn:schemas-upnp-org:device:MediaServer:1
---------------------------------------------
Device Name: 192.168.0.6 - Sonos CONNECT:AMP
Unique Device Name: uuid:RINCON_000E5726C94601400
Description: Sonos CONNECT:AMP
Model Name: Sonos CONNECT:AMP
Model Number: ZP120
Serial Number:
Manufacturer Name: Sonos, Inc.
Manufacturer URL: http://www.sonos.com/
Type: urn:schemas-upnp-org:device:ZonePlayer:1

This output is fine but it is not done in a PowerShell way. Newcomers to PowerShell often make things needlessly complex. While the above script works it is not the best way do list all UPnP devices. Let’s make the above code easier and more importantly, more useful:

$finder = New-Object -ComObject UPnP.UPnPDeviceFinder;
$devices = $finder.FindByType("upnp:rootdevice", 0)
$devices

This script will give the same output but much more useful. Line one instatiates the UPnP COM object, line two tells the oject to find all ‘root’ UPnP devices on our local network and store the result in the $devices variable. The third line is a bit of PowerShell magic. Since the variable $devices is really an object PowerShell understands that it contains many objects inside itself. So by simply stating the variable name $devices on a single line PowerShell will output the object properties like this:

IsRootDevice     : True
RootDevice       : System.__ComObject
ParentDevice     :
HasChildren      : False
Children         : System.__ComObject
UniqueDeviceName : uuid:4d696e69-444c-164e-9d41-101f743be078
FriendlyName     : BUBBA
Type             : urn:schemas-upnp-org:device:MediaServer:1
PresentationURL  : http://192.168.0.9:8200/
ManufacturerName : Justin Maggard
ManufacturerURL  : http://www.debian.org/
ModelName        : Windows Media Connect compatible (MiniDLNA)
ModelNumber      : 1
Description      : MiniDLNA on Debian
ModelURL         : http://www.debian.org/
UPC              :
SerialNumber     : 12345678
Services         : System.__ComObject

IsRootDevice     : True
RootDevice       : System.__ComObject
ParentDevice     :
HasChildren      : True
Children         : System.__ComObject
UniqueDeviceName : uuid:RINCON_000E5836C94601400
FriendlyName     : 192.168.0.6 - Sonos CONNECT:AMP
Type             : urn:schemas-upnp-org:device:ZonePlayer:1
PresentationURL  :
ManufacturerName : Sonos, Inc.
ManufacturerURL  : http://www.sonos.com/
ModelName        : Sonos CONNECT:AMP
ModelNumber      : ZP120
Description      : Sonos CONNECT:AMP
ModelURL         : http://www.sonos.com/products/zoneplayers/ZP120
UPC              :
SerialNumber     :
Services         : System.__ComObject

Admittedly this doesn’t look as pretty as the output from the first script. But, the result is a true objectand much more useful. In order to see what information is available, issue the most useful PowerShell command of all, Get-Member:

$devices | Get-Member

   TypeName: System.__ComObject#{3d44d0d1-98c9-4889-acd1-f9d674bf2221}

Name             MemberType Definition                            
----             ---------- ----------                            
IconURL          Method     string IconURL (string, int, int, int)
Children         Property   IUPnPDevices Children () {get}        
Description      Property   string Description () {get}          
FriendlyName     Property   string FriendlyName () {get}          
HasChildren      Property   bool HasChildren () {get}            
IsRootDevice     Property   bool IsRootDevice () {get}            
ManufacturerName Property   string ManufacturerName () {get}      
ManufacturerURL  Property   string ManufacturerURL () {get}      
ModelName        Property   string ModelName () {get}            
ModelNumber      Property   string ModelNumber () {get}          
ModelURL         Property   string ModelURL () {get}              
ParentDevice     Property   IUPnPDevice ParentDevice () {get}    
PresentationURL  Property   string PresentationURL () {get}      
RootDevice       Property   IUPnPDevice RootDevice () {get}      
SerialNumber     Property   string SerialNumber () {get}          
Services         Property   IUPnPServices Services () {get}      
Type             Property   string Type () {get}                  
UniqueDeviceName Property   string UniqueDeviceName () {get}      
UPC              Property   string UPC () {get}

As you can see in the above output we get a number of properties and one method, IconURL. Now you can pick and choose which properties you want and you can do magic with them. Let’s say you want the FriendlyName, ModelName and the ManufacturerName. Try this:

$devices | Select-Object FriendlyName, ModelName, ManufacturerName

The great thing here is that you can pick and choose exactly the output you want. In a later post I will show you what you can do with this.

Generate passwords using PowerShell

The other day I needed to generate some 1400+ new user passwords. Being a lazy person I figured that PowerShell could rescue me. This is what I did to check that my idea worked:

PS C:\> Add-Type -AssemblyName "System.Web"
 PS C:\> [System.Web.Security.Membership]::GeneratePassword(10,2)
 35&OjFtM^k

As you can see this generates a password that is 10 characters in length and contains at least 2 non-alphanumeric characters. Now all I needed was to iterate this 1400 times and then output the result to the clipboard, simple as pie:

PS C:\> 1..1400 | % { [System.Web.Security.Membership]::GeneratePassword(10,2) } | clip

And that is a 1400 new passwords stored in the clipboard. I can now paste these or pipe them into a set password routine.