Monday, February 27, 2012

Remote Desktop session shortcut keys

I thought I knew where this was.  I had a link to it.

Guess what?  The link moved and the article changed.

To prevent this in the future I am simply copying this and pasting it here.

The original source is: http://msdn.microsoft.com/en-us/library/windows/desktop/aa383500(v=vs.85).aspx

How long that remains is anyone’s guess.

But, I now have the important bits here.

The following is a list of the Remote Desktop Services shortcut keys.  Use these commands within a a Remote Desktop session when lacking mouse control.

ALT+PAGE UP  =  Switches between programs from left to right.

ALT+PAGE DOWN  =  Switches between programs for right to left.

ALT+INSERT  =  Cycles through the programs in the order they were started.

ALT+HOME  =  Displays the Start menu.

CTRL+ALT+BREAK  =  Switches the client between full-screen mode and window mode.

CTRL+ALT+END  =  Brings up the Windows Security dialog box.

ALT+DELETE  =  Displays the Windows menu.

CTRL+ALT+MINUS SIGN (-)  =  Places a snapshot of the active window, within the client, on the Remote Desktop Session Host (RD Session Host) server clipboard (provides the same functionality as pressing ALT+PRINT SCREEN on the local computer).

CTRL+ALT+PLUS SIGN (+)  =  Places a snapshot of the entire client windows area on the RD Session Host server clipboard (provides the same functionality as pressing PRINT SCREEN on the local computer).

Note that on an NEC98, the following shortcut keys are different:

  • CTRL+ALT+BREAK is replaced by F12.
  • CTRL+ALT+END is replaced by 15.

Wednesday, February 22, 2012

Uninstalling the SCVMM Agent from Server Core

Okay, I admit it, I screwed up.

In testing the various releases of SCVMM 2012 I dorked up my environment.  I tossed away my database when moving between builds. 

And then when I wen to re-add my Hyper-V Servers I got an error that an unsupported version of the agent is installed.

Okay, fine - I thought.  I will simply uninstall it.  Um..  But this is Server Core I am using.  There is no Control Panel, Uninstall a program.

This article is more about doing something on Server Core than fixing my SCVMM 2012 situation.

Okay.  Well, um.  Regedit works on Server Core.  Okay fire that up.  But I don’t want to manually clean the registry, there must be something useful there though.  And a bit of searching pointed me where I need to be:

HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall

This is where all the good programs go that use Windows Installer.

Under here I found the Virtual Machine Manager Agent.  And under that I found a very useful Registry Key:  “UninstallString

The UninstallString key is a string value.  It is the command line option that is invoked when uninstall is performed.  How super handy (I think I might use this all the time).

At your command prompt, run the string you find there and you will be ready to finish repair.

Monday, February 13, 2012

Skimming a Hyper-V Service Event log with PowerShell

We are all used to opening up our friend the EventLog Viewer GUI.

But what do you do when you don’t have the GUI (Server Core or Hyper-V Server for example)?  How do you get to those trusted events?

Well, PowerShell of course!  And there are even two different cmdlets to get there.

Get-EventLog and Get-WinEvent

Get-EventLog focuses on the top level event logs; Application, System, PowerShell, Security.

Get-WinEvent can get you anything, any event log.  the hardest part is identifying the Event Logs for Get-WinEvent.

Recently I have been focused on disk conversion, so lets focus on that.  VHD conversion events are in the Hyper-V Image Management event log under the Operational log.

The Hyper-V Image Management service manages VHDs (disk images) and this is also an event provider. 

If you type; get-winevent -ProviderName "Microsoft-Windows-Hyper-V-Image-Management-Service"

you will get all events, Admin and Operational.  In my case I just want Operational events, so I can do direct to the log.

get-winevent -LogName Microsoft-Windows-Hyper-V-Image-Management-Service-Operational

I cheated when I went looking for the logs, you can’t browse them like the tree view in the GUI.  I used the GUI on one server to locate the log I needed and I inferred its name from the Properties screen.

The series of EventIds that I even care about are:

  • 15110 - creating a VHD
  • 15111 - successfully created (finished creating)
  • 15106 - converting a VHD from dynamic to fixed
  • 15107 - successfully converted (finished converting)
  • And any fails, but didn’t find any

    What I know is that I have a VM name in the SCVMM job log that I want to find the corresponding Hyper-V event(s).  That should give me something to filter on.  In the GUI I see the information in the General TAB, in the event object this is in the Message property.

    get-winevent -LogName Microsoft-Windows-Hyper-V-Image-Management-Service-Operational | where {$_.Message -match "Xd1kD0229"}

    In my case the name of the VM is “Xd1kD0229” and in searching the message of the Event this gives me any instance where this string of characters occurs.  In most of the events it is a folder in the Literal Path of the VHD file.

    Now, how might you get PowerShell enabled on Server Core or Hyper-V Server?

    At the Command prompt you can add the PowerShell and .Net features:

    DISM /Online /Enable-Feature /FeatureName: NetFx2-ServerCore

    DISM /Online /Enable-Feature /FeatureName: NetFx3-ServerCore

    DISM /Online /Enable-Feature /FeatureName: MicrosoftWindowsPowerShell

    You can then launch PowerShell in the same shell session:

    C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

  • Tuesday, February 7, 2012

    Grouping and averaging time to execute execute SCVMM 2012 Jobs with PowerShell

    In my previous post I ended with a large array of System Center Job Objects.

    I need to now determine how long each job took to execute.  And since these are many jobs over time, I want to see if the time to execute changes over time.

    So, I need to sort.  I have my array from the previous post.  To sort I do this:

    $vhdConvertJobs = $vhdConvertJobs | Sort StartTime

    This will sort all Job objects in the Array ( $vhdConvertJobs )using the StartTime property of the Job object. 

    Nice and conveniently each job has a StartTime and EndTime, so I just need to subtract those.  The subtraction part is easy:

    Foreach ($job in $vhdConvertJobs) {
        ($job.EndTime - $job.StartTime).seconds
    }

    Now the interesting part.  I have a huge list of numbers.  Great.  I could graph them. No.

    I had this great idea to group them into groups of ten and then average them.  So my averages are the first ten, then the second ten, and so on.  That is a bit easier to look at.

    $i = $vhdConvertJobs.Count
    $arrayTick = 0

    While ($arrayTick -lt $i){
        $loopTick = 0
        While ($loopTick -ne 10){
            $timeToConvert = $timeToConvert + ($vhdConvertJobs[$arrayTick].EndTime - $vhdConvertJobs[$arrayTick].StartTime).seconds
            $loopTick++
            $arrayTick++
            if ($arrayTick -eq $i){break}
        }
        "Average of " + $loopTick + " jobs: " + ($timeToConvert / $loopTick) + " seconds"
        $TimeToConvert = 0
    }

    Put this all together and it looks like this:

    <#
    .SYNOPSIS
       This script is dump the time to convert VHDs form Dynamic to Fixed from SCVMM 2012
    .DESCRIPTION
       It first finds the VMs using the name match pattern (or you can leave that commented to simply get all VMs)
       Then It finds the virtual disk and the latest job on the virtual disks.
       The jobs are sorted from first started to last started.
       The different from StartTime to EndTime is output.
       Then the Jobs are averaged as groups of 10 and groups of 100 from first started to last started.
    .AUTHOR
        Brian Ehlert, MSFT VM MVP

    .KNOWN ISSUES
       In SCVMM Jobs age and the last job on an object changes.  So there is a timeliness to running this script.  If you
       wait too long you will get an incorrect number of jobs back.
    #>


    Import-Module VirtualMachineManager

    $vhdConvertJobs = @()

    $scVMs = Get-SCVirtualMachine | where {$_.Name -match "Xd1K"}

    Foreach ($scVM in $scVMs){
        $vhdConvertJobs += [Microsoft.SystemCenter.VirtualMachineManager.Task]( Get-SCVirtualDiskDrive -VM $scVM | where {$_.MostRecentTask -match "convert"} ).MostRecentTask
    }

    $vhdConvertJobs = $vhdConvertJobs | Sort StartTime

    ""
    "Disk Conversion Jobs"
    "Listed first are the jobs started earlier, listed last are the jobs started later"

    Foreach ($job in $vhdConvertJobs) {
        ($job.EndTime - $job.StartTime).seconds
    }

    ""
    # Break the sorted list of jobs into groups of 10, Average the seconds to convert per group
    "Disk Conversion Job Average per 10 conversions"
    "Sorted by StartTime.  First are the first jobs started, last are the later jobs started"

    $i = $vhdConvertJobs.Count
    $arrayTick = 0

    While ($arrayTick -lt $i){
        $loopTick = 0
        While ($loopTick -ne 10){
            $timeToConvert = $timeToConvert + ($vhdConvertJobs[$arrayTick].EndTime - $vhdConvertJobs[$arrayTick].StartTime).seconds
            $loopTick++
            $arrayTick++
            if ($arrayTick -eq $i){break}
        }
        "Average of " + $loopTick + " jobs: " + ($timeToConvert / $loopTick) + " seconds"
        $TimeToConvert = 0
    }


    ""
    # Break the sorted list of jobs into groups of 100, Average the seconds to convert per group
    "Disk Conversion Job Average per 100 conversions"
    "Sorted by StartTime.  First are the first jobs started, last are the later jobs started"

    $i = $vhdConvertJobs.Count
    $arrayTick = 0

    While ($arrayTick -lt $i){
        $loopTick = 0
        While ($loopTick -ne 100){
            $timeToConvert = $timeToConvert + ($vhdConvertJobs[$arrayTick].EndTime - $vhdConvertJobs[$arrayTick].StartTime).seconds
            $loopTick++
            $arrayTick++
            if ($arrayTick -eq $i){break}
        }
        "Average of " + $loopTick + " jobs: " + ($timeToConvert / $loopTick) + " seconds"
        $TimeToConvert = 0
    }