Weird issues when msxml3.dll fails

  • Symptoms
  • I’ve recently had the following symptoms on a computer:

    • Clicking on ‘properties’ after right click on ‘computer’ in the start menu doesn’t do anything

      computer-properties

    • I cannot launch eventvwr.msc or eventvwr.exe without getting an error message although I can launch mmc.exe and load the snap-in successfully to read the eventlogs
      mmc-fail
    • Opening the Windows Update applet from the Control Panel doesn’t work
    • the AV UI fails
      AV-fails
    • The volume shadow copy service complains all the time
      Volume Shadow Copy Service error: Unexpected error calling routine CoCreateInstance. hr = 0x80040154, Class not registered

      VSS-2

    • The servicing stack is idle and running the System Update Readiness tool to fix Windows corruption errors fails with the following error message:
      Windows update could not be installed because of error 2147746132 “Class not registered”
      wusa-fails

      wusa-fails-2
      NB: I can still extract what’s in the Windows6.1-KB947821-v34-x64.msu file and run checksur.exe manually.

  • More clues
    • The WindowsUpdate.log file indicates:
      WU-log
    • The volume shadow copy service also reports
      VSS-1
    • and clicking “manage” after right-clicking ‘computer in the start menu ends with the following error message:
      msxml3.dll is either not designed to run on Windows or it contains an error
      msxml-error
  • What’s the problem
  • Everything says msxml3.dll has a problem. Right?

  • What’s the root cause
    • The msxml3.dll is actually empty:
      msxml-error-2
    • and the CBS logs says, it started applying a package supposed to replace msxml3.dll
      CBS-1
    • but 2 minutes later, it reported it cannot parse XML anymore
      CBS-2
    • What happened during these 2 minutes….is actually a power loss :-(
      loss-power
  • My fix
  • # Gather all msxml3.dll files under %windir%
    $all = dir C:\Windows\* -inc msxml3.dll -rec -for -ea 0
    # restore the most recent version from the component store
    robocopy ($all | Where { $_.FullName -match "amd64" } | sort lastwritetime | Select -Last 1).Directory C:\Windows\system32  msxml3.dll /B
    # register the dll
    regsvr32 C:\Windows\system32\msxml3.dll
    # if that fails, try with the n-1 version
    robocopy ($all |
    Where { $_.FullName -match "amd64" } |
    sort lastwritetime |
    Select -last 2)[0].Directory C:\Windows\system32  msxml3.dll /B
    regsvr32 C:\Windows\system32\msxml3.dll
    
  • Steps to reproduce the problem
  • # unregister the dll
    regsvr32 /u C:\Windows\system32\msxml3.dll
    # create an empty file
    New-Item C:\Windows\temp -Name msxml3.dll -ItemType File
    # stop services that lock msxml3.dll
    Stop-Service -Name WSearch,WinRM -Verbose
    # kill processes that lock msxml3.dll
    taskkill /im explorer* /f
    # restore the file (ab)using the backup privilege
    robocopy C:\Windows\temp c:\windows\system32 msxml3.dll /r:0 /B
    

    Trigger ConfigMgr client actions

    A few weeks ago, I came across the following article on refreshing the System Center Configuration Management client

    Whenever I see a script, I always wonder, could it be done with a oneliner ?
    sms_client-actions-01

    As long as the script doesn’t care about the order of the ConfigMgr actions to be performed, yes, it’s achievable this way:

    (New-Object -COM 'CPApplet.CPAppletMgr').GetClientActions() | 
    Where { 
        $_.Name -match "(\sPolicy$)|(Collection\sCycle$)|(Updates)"
    } | ForEach-Object {
        try {
            $_.PerformAction()
            Write-Verbose -Message "Successfully executed $($_.Name)" -Verbose
        } catch {
            Write-Warning -Message "Failed to execute $($_.Name)"
        }
    }
    

    I’ve even added some filtering on action names and error handling.

    sms_client-actions-02
    There’s always more than one way to skin a cat with PowerShell ;)

    How to use WDS to PXE Boot a Nano Server VHD with PowerShell

    Last week I was renewed as a Windows PowerShell MVP MVP-2015-award, my article about how to use WDS to PXE Boot a Nano Server VHD with PowerShell was published on PowerShell Magazine and even mentioned on the Nano Server blog. Awesome, isn’t it :-D
    I’d like to thank everyone who enjoys my work, reads my blog, supported me and helped me along the way. I wouldn’t have been awarded without you. Again, a big thank you! I’m very pleased and honoured to receive this award and be part of this amazing PowerShell community :)

    PowerShell oneliner contest

    The pipeline in PowerShell offers an avenue to solve many issues with oneliners.
    My fellow Windows PowerShell MVP Carlo Mancini proposed a very interesting and high quality oneliner contest. Perfect, challenge accepted :D
    After reading the rules twice, I jumped into trying to figure out what’s the best approach to get the shortest solution for each puzzle. I usually focus on the approach before trying to shorten my solution because when you started digging in a hole, it’s hard to get out of it and come with a brand new approach to solve the puzzle.

    • Task 1: get the absolute value of the highest double floating point in an array

    I noticed that the match operator with a regular expression allowed to filter out only double.

    $n = -1,-2,-5,-8.9,'b',-9.11,-6,-3,-2,-9.1,-1,-1.4,'a'
    
    # match with regular expression
    $n -match '\d\.'
    
    # vs. a more classic approach
    $n | ? { $_ -is [double] }
    

    There were only negative double numbers in the array. To get the shortest absolute value, I just multiplied by -1 instead of using the abs method of the [math] .Net class.

    # .Net abs approach
    [math]::abs(-1.4)
    
    # vs. me cheating ;)
    -1.4*-1
    

    After bringing all the pieces together, my shortest solution for task 1 is:

    # task 1
    ($n-match'\.'|sort)[-1]*-1
    

    posh-contest-task1

    • Task 2: display 12345 as a int32 without using digits

    To solve this task, my idea/approach was to use hexadecimal and do some substractions

    0xb-0xa -eq 1
    0xc-0xa -eq 2
    0xd-0xa -eq 3
    0xe-0xa -eq 4
    0xf-0xa -eq 5
    

    …except that I can’t use the leading 0.
    So, I wondered how do I get a hexadecimal without using the 0x notation.
    Well the answer is:

    # you can actually do 
    [char]'f' - [char]'a'
    

    My shortest solution for task 2 is:

    # task 2
    [int]-join('b','c','d','e','f'|%{([char]$_-[char]'a')})
    

    posh-contest-task2

    • Task 3: Display PowerShell from ‘X ‘

    When I saw this puzzle, I immediately thought, use only 1 occurrence of ‘X ‘, get rid of the whitespace behind X and use the ascii table to get P from X, o from X, w from X,…

    My shortest solution was:

    #task 3 split for readability
    -join(
    -8,23,31,13,26,-5,16,13,20,20|%{
    [char]($_+[int][char]('X '-replace' ',''))
    })
    

    posh-contest-task3

    PowerShell rocks 8-) and Bravo Carlo, I enjoyed this very nice contest :-)

    Bonus: my favourite PS golfer Bartek also proposed his solutions: https://becomelotr.wordpress.com/2015/07/04/the-only-golf-i-play/

    A simple PackageManagement (aka Oneget) Provider for Windows Update

    One of the breaking changes that comes along with PowerShell 5.0 is OneGet PackageManagement.
    What is OneGet? Oneget is a package providers source aggregator, a unified package management tool like APT is on Linux.

    When I said like Linux, I also meant it’s open-source :D and that you can actually write your own provider. The list of desired package providers is listed on this page.

    To get a better understanding of what OneGet PackageManagement is, I’d recommend you read these two posts:

    To get my hands-on this new tool on Christmas holidays, I wrote a prototype for the Windows Update Agent (WUA) provider that can query dynamically updates from locally registered sources: Windows Update (by default), Microsoft Update (after opt-in), WSUS, the Windows Store,… Unfortunately, I can’t present this code as it’s too clunky with the latest PackageManagements builds over the last 6 months. To get things working smoothly, I revised the code and tried to keep it simple. This post will present a Windows Update Agent provider that exclusively queries only 1 source: Windows Update. It could probably meet the following expectations recently reported on MS connect website:
    WU-provider-feedback

    Let’s see how this provider works:

    • List package providers and sources available on the box
    • WUA-01

    • List what was installed from Windows Update on the box
    • Get-Package -ProviderName WUA
      

      WUA-02

    • Install missing updates from Windows Update
    • Find-Package -Source  'Windows Update' | Install-Package
      

      WUA-03

    Bonus: To be able to see what happens behind the scene and be able to choose and confirm the updates you want to install, you can do:

    Find-Package -Source  'Windows Update' -Debug | 
    Install-Package -Debug
    

    I’ve hosted the Windows Update Agent provider for Windows Update on github using this link: https://github.com/p0w3rsh3ll/OneGetWUAProvider

    By the way, I’m not the only one who writes PackageManagement providers using PowerShell.
    Windows PowerShell MVP Doug Finke already wrote two providers for gist and github that inspired me and helped me while working on mine :-D

    system.environment OSVersion property

    I was using the Get-LatestWMF5 function in the ISE on a Windows 2012 R2 (PowerShell version 4.0 by default) and it downloaded the wrong file :(

    I was using the [system.environment] .Net class to get the version of the Operating System.
    It works fine in the console but not in the ISE.

    As you can see, it’s reported as 6.2 which means Windows 8/2012 although I’m on Windows 2012 R2.
    ISE.v4

    There’s actually a change introduced the API that controls this behavior.
    It’s documented on this page: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724451%28v=vs.85%29.aspx
    VersionExAPI
    Windows PowerShell MVP Dave Wyatt provided this link. Thx Dave :)

    I propose to replace the code that uses the

    [environment]::OSVersion.Version

    prev.code.getlatestWMF5
    by this:

    [Version]$((Get-CimInstance Win32_OperatingSystem).Version)
    

    Get the latest WMF5

    Michael Greene tweeted the following a few days ago
    M.Greene-tweet-wmf5latest

    I love his idea and his code shows a few awesome tricks I ignored:

    I propose the following improvements:

    • Insert a require statement to tell people that the code is only v3 compatible. There’s no Invoke-Webrequest in PowerShell 2.0.
    • Download the required version based on the OS where you run the code. If you’ve PowerShell 3.0 on Windows 7 64bit, you’ll get the Windows6.1-KB2908075-x64.msu file, etc.

    Let’s have a look at my proposal

    On Windows 10, you don’t need this piece of code, so you’ll just get a warning:
    get-latestwmf5-onWX

    On Windows 7 as of PowerShell 3.0, you get the following experience:
    get-latestwmf5-onW7

    On Windows 2012 R2, you’ll experience the following:
    get-latestwmf5-onW81

    Last warning: WMF 5.0 requires .Net Framework 4.5, make sure this requirement is met before installing the WMF 5.0.