Formatting a removable USB drive with 2 partitions

TL;DR – Starting with Windows 10 Insider Preview Build 14965, you can format any “Removable” USB Flash Drive with more than one partition. Perfect for installation of large (over 4GB) WIM files on UEFI machines!

 

Hey all, back from a week at the Microsoft MVP summit, a Week in the UK, and a week in Arizona.

A few weeks ago at the Microsoft MVP summit, an engineering manager with the Windows Product group made an offhand comment about formatting a removable USB drive with two partitions. This took several of us by surprise, because historically, this hasn’t been supported widely without converting to a Fixed disk or something.

Mike Terrill (and Mike Niehaus) already beat me to the punch with some posts, but I wanted to share my results. :^)

The Background

Why is this important? Well as I mentioned in another blog post, as more and more people are booting to UEFI, on USB flash drives formatted with Fat32, with WIM images over 4GB in size, that causes a problem because Fat32 can’t hold files over 4GB in size.

Another solution would be to use the Rufus tool to split a USB drive into multiple partitions with a hidden fat32 partition. However, the problem here is that the hidden partition uses a special UEFI app that is not signed, so it won’t work on UEFI machines with Secure Boot enabled.

This has become even more interesting since Windows Server 2016 came out, with a base WIM image for standard Server SKU that is over 4GB in size. Hum…

The Hardware

20161126_200856.jpg

I tested on several different USB makes using my Windows 10 (version 1607) laptop. Some would allow me to create a 2nd partition on a removable Flash Drive, others would not giving me an error:

DISKPART> create part pri

No usable free extent could be found. It may be that there is insufficient 
free space to create a partition at the specified size and offset. Specify
different size and offset values or don't specify either to create the maximum 
sized partition. It may be that the disk is partitioned using the MBR disk
partitioning format and the disk contains either 4 primary partitions, (no
more partitions may be created), or 3 primary partitions and one extended
partition, (only logical drives may be created).

Mostly the older and/or cheaper drives didn’t work, but most of the newer and/or name brand drives did work.

Finally I narrowed it down to two different models, both my favorites:

Then I tested against three Operating Systems: Windows 10 Version 1607, Windows 10 Preview, and Windwos 7.0 SP1. All using Diskpart to create multiple partitions.

The script

Diskpart.exe –>

sel disk 1
clean
create part pri size=450
format quick fs=fat32
assign
create part pri
format quick fs=ntfs
assign
exit

The Results:

                                 SanDisk           Transcend
Windows 7 SP1 Build 7601           Pass               Fail
Windows 10  Version 1607           Pass               Fail
Windows 10 Preview 14965           Pass               Pass   

I was able to format my SanDisk into multiple partitions using Windows 7 and beyond.

But I was not able to format the Transcend drive into multiple partitions using Windows 7 or Windows 10 Version 1607, but I was able to partition into multiple partitions on the new Windows 10 Insider Preview 14965.

That’s new!

I haven’t done enough testing using the removable flash drives on older machines, to see if the partitions are still visible, but the results look promising for a start.

Update #1 – 11/28/16:

Found out today that the reason that my SanDisk Extreme disk worked on Windows 7 and Windows 10 1607 may be because the removable Flash disk is reported as “Fixed” rather than “Removable” to the OS. Link.

Update #2 – 11/28/16:

I noticed that when taking the “removable” disk formatted with 2 partitions from Windows 10 Preview 14965 over to Windows 10 Version 1607, only the first partition was visible. As a work around I tried moving the main NTFS partition first and the Fat32 partition second.

sel disk 1
clean
create part pri
shrink desired=450
format quick fs=ntfs
assign
create part pri
format quick fs=fat32
assign
exit
Advertisement

Field Notes – Dell Command PowerShell Provider

Working today with Mike Terrill on some advanced queries using the Dell Command – PowerShell Provider with Configuration Manager.

Dell Command – PowerShell Provider

Dell provides a PowerShell provider to query and manage various system level components on Dell machines. This is great if you are using PowerShell to process the output, and perform complex tasks, more complex than a simple static command line.

Configuration Manager Compliance Settings

My friend Mike Terrill called me up today and wanted to use Configuration Manager “Compliance and Setting Management” to push out a PowerShell script, with the Dell Command PowerShell Provider” to query the hardware state of a machine.

OK, cool. That’s when we came across some challenges.

We can add a PowerShell script, cool. But we need a test defined in Configuration Manager to determine if the test passed or failed.

Say our PowerShell script ran, with the following output.

Ready to run test[1]...
Test Result: Success

We could program ConfigMgr to see if the output “contains” the value “success”.

Except, in this case the script would fail because ALL lines in the output must contain the value “Success”. The first line didn’t contain the string “success”!?!? That’s what ConfigMgr is looking for. <sigh>

So we just need to make sure that *ALL* lines on the script are written by our script, and that we output *only* what’s necessary…

Dell and console output

Now the challenge is that the Dell Command – PowerShell provider is writing something extra to the console, and messing up our test in ConfigMgr. Recall that *all* lines in the output need to contain our test, the “To get more help…” command was messing with our tests.

capture

I decided to dig a little deeper and see if the output could be disabled or redirected ( say redirect in powershell to out-null), but no! So I broke out my favorite C# decompile, but alas, no of all the crazy things, the code is writing to the C# Console, and no way to bypass.

capture-2

Work Arround

Eventually we came across a horrible, no good, low down, dirty work around. Here is an example of the script:

import-module DellBIOSProvider

$DidTestPass = <# Perform a query here!#>  
 
if ( $DidTestPass ) 
{
    write-host "To get more help about the Dell Command PowerShell provider"
}
else
{
    write-host "Machine did not pass this test. Output more info here!"
}

Yes, in this case we output the dell string “To get more help…”  Then we can set Configuration manager Compliance Settings to look for the value to contain “To get more help about the Dell Command PowerShell Provider”. Anything else in this case is an error and will be written to the log for analysis later.

Bugs

There are two bugs here:

  1. The Dell PowerShell provider should not be outputting the “to get more help” string, or at least provide a way to disable, via registry key or something.
  2. The Microsoft Configuration Manager Compliance Settings should be able to look for a substring within the *entire* output, rather than looking for a substring in every line.

Keith

Turn off CM PowerShell update warnings

So I’ve been working in some strange Configuration Manager environments lately, sometimes they are not always up to date, yea… yea… I know. But they are test environments, so you know.

Problem

One of the problems I have is that when I call some CM PowerShell CmdLets, I get a warning:

erro1.JPG

WARNING: an update to the System Center 2012 Configuration
Manager Cmdlet Library is available. Please go to 
'http://go.microsoft.com/fwlink/?LinkId=<something>' 
to download the latest version. Running cmdlet version: 
<someversion> Latest cmdlet version: <someversion>.

Well the output has been driving me nuts, and I finally decided to dig into the problems and find out how to suppress the message.

A Hint

Niall Brady has a blog post on the subject:

How to fix “Warning: An update to the System Center 2012 Configuration Manager Cmdlet Library is available.”

But his recommended fix is to install the latest cmdlet library, well, I suppose I could do that, but I was wondering if there was an easier. way.

Reverse Engineering

I decided to do some reverse Engineering.

  • What dll files to the CM PowerShell cmdlets live?
    get-command get-cmsite | format-list *
    Unfortunately, did not reveal too much.
  • Did a Grep of the dll’s to find the error message, same files.
  • Finally able to track down the function: get-CMCmdletUpdateCheck and a match to the error string
  • Skip the Update? Yes I want to skip the update, that looks like it’s what I want.
    code1.JPG

Well it turns out this was a round about way to the Get-CMCmdletUpdateCheck Cmdlet which does what I was looking for.

Example

Simply run Set-CMCmdletUpdateCheck with -IsUpdateCheckEnabled $False to suppress the output:

Set-CMCmdletUpdateCheck -CurrentUser -IsUpdateCheckEnabled $False

 

code2.JPG

Nice and quiet :^)

 

BIOS to UEFI SecureBoot on Lenovo Desktops Gotcha! Part II

Good news for those IT departments out there that want to automated the process of moving from BIOS to UEFI with Secure Boot on Lenovo Desktop Machines!

As you may recall from my last post, I’ve been struggling to get any Lenovo Desktop Machines to move from non-SecureBoot to SecureBoot. But I recently found out that Lenovo may have updated their BIOS to support this (could it be?) We got a tentative confirmation from our contact at Lenovo, so it was time to do some testing.

I got a Lenovo M700 Tiny (great machine), and updated to the latest BIOS version. Looks like the BIOS version created Aug 2016 added some SecureBoot functionality. Looking good!

I created a tool internally at 1E to test moving from various BIOS/CSM/UEFI/SecureBoot/MBR/GPT states, so I ran the tool, and low and behold, it passed. The new M700 Tiny Firmware update allows for Non-SecureBoot to SecureBoot.

I haven’t tested other Lenovo Desktops (yet), but I’m cautiously Optimistic that the M73/83/93 will be updated as well. For several of our customers, that’s a major percentage of machines that can now be updated.

The next thing to talk to Lenovo about is to change Laptops functionality so we can turn on UEFI with CSM support and without SecureBoot. This would allow us to install Windows 7 in UEFI mode.

Looking forwards to Microsoft Ignite in Sept 2016!

( Thanks Joe! :^)

BIOS to UEFI SecureBoot on Lenovo Desktops Gotcha!

Been working with several IT departments trying to get our BIOS to UEFI solution qualified on as many OEM hardware models as possible, but unfortunately we have hit a snag that will affect Lenovo customers who need to move from BIOS to UEFI with SecureBoot using automated tools.

Lenovo does have an WMI API for programmatically making changes to the BIOS from within Windows (either the full OS or WinPE). That’s great! Unfortunately there are two areas where their implementation is lacking compared to Dell or HP:

  1. On Lenovo Laptops, we can change from BIOS to UEFI with SecureBoot, but they don’t offer the ability to move from BIOS to UEFI without SecureBoot. Why would we want to do that? Well if we were installing Windows 7 in UEFI mode (with anticipation of upgrading to Windows 10 with SecureBoot in the future).
  2. On Lenovo Desktops, the opposite problem, we can change from BIOS to UEFI without SecureBoot, but we can’t change to BIOS to UEFI with SecureBoot. And this is a problem.

I did contact Lenovo directly, and their official response is that they are aware of the issue, but the lack of support for API access to/from SecureBoot on desktop models is “by-Design”. Lenovo is only half right, Disabling Secure Boot must always require physical presence, that is clearly documented by UEFI spec:

http://www.uefi.org/sites/default/files/resources/UEFI_Secure_Boot_in_Modern_Computer_Security_Solutions_2013.pdf

 DISABLING SECURE BOOT 

[…]

Users may disable Secure Boot entirely, using a system setup screen enabled at boot time. Each manufacturer has its own interface for this option. In all cases, end user must be physically present to establish proof of possession (POP) associated with the changes.

However, Enabling secure boot has no such requirement (that I can find), and Dell, HP, and Lenovo ThinkPad devices do support enabling SecureBoot programmatically.

I have tried to explain this point to Lenovo, but to no success. This sucks for customers that need to use tools to make changes at scale. Manually enabling SecureBoot can be a labor intensive process.

Recommendation:

Therefore, I have to unfortunately make the recommendation:

Guidance: Enterprise customers should avoid Lenovo Desktops if they are still using Windows 7 and have plans to upgrade to Windows 10 with SecureBoot in the near future. Lenovo does not have any enterprise management tools to support this.

-Keith

Display WPF XAML code in PowerShell

Last week I went to the Minnesota Management Summit at the Mall of America #MMSMOA, and I got inspired to work on a few projects in my backlog.

One of the presentations I went to was with Ryan Ephgrave (@EphingPosh on Twitter.com), and his talk on “Better Know a PowerShell UI“.

Overall it was a great presentation, and I learned a lot. And got me thinking about some of the things I could do with a framework I started earlier in the year but never got around to finishing.

WPF4PS

Without further adieu, I present Windows Presentation Framework for PowerShell (WPF4PS). It is also the first project I’ve released as source code on GitHub:

https://github.com/keithga/WPF4PS

Background

Most WPF + PowerShell examples are created with a lot of custom code to add in event handlers for the User Interface elements. The goal is to find all control elements on the page and if there is a pre-defined function created, then use it. Which means minimal code for overhead.

Example

Here is a fully functional example:

  • Load the WPF4PS module
  • Import a XAML defined in Visual Studio
  • Create a scriptBlock to handle the button Click
  • Create a HashTable to pass data between our script that the XAML Window
  • Call the Show-XAMLWindow function
  • Get the value of the TextBox from the Hash

wpf4ps

<#
.SYNOPSIS
WPF4PS framework Examples

.DESCRIPTION
Simple Example

.NOTES
Copyright Keith Garner, All rights reserved.

#>

[cmdletbinding()]
param()

import-module $PSScriptRoot\wpf4ps -force

$MyXAML = @"
<Window x:Class="WpfApplication1.MainWindow"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 xmlns:local="clr-namespace:WpfApplication1"
 mc:Ignorable="d"
 Title="MainWindow" FontFamily="Segoe WP Semibold" Width="400" Height="300" Name="WindowMain" >
 <Grid>
 <Label>Hello World</Label>
 <Button x:Name="Button1" Content="Big Red Button" Width="125" Height="25" Background="#FFDD0000" Margin="0,60,0,0"/>
 <TextBox x:Name="textBox1" Height="23" Width="200" />
 </Grid>
</Window>
"@

$MyControl = [scriptBlock]{

    function global:button1_click()
    {
        "Click the Big Red Button`n" + $TextBox1.TExt  | show-MessageBox 
        $WindowMain.Close()
    }

}

$MyHash = [Hashtable]::Synchronized(@{ textBox1 = "Hello World" })

Show-XAMLWindow -XAML $MyXAML -ControlScripts $MyControl -SyncHash $MyHash

$MyHash.TextBox1 | Write-Host

Next

My goal is to work out the kinks and eventually upload/share this on PowerShellGallery.com.

For example:

  • I created two Show-XAMLWindow() functions in the library, one inline and another Async. I still don’t know what the usage case of Async is.
  • Ryan Ephgrave did some XAML + Powershell examples in his “Better Know a PowerShell UI” blog series with XAML “Binding” elements, something I have not used in the past, so I excluded them from this package.
  • I had to do some weirdness with the declaring the functions above as “global” to make them visible to the Module

If you have feedback on the layout or usage, please let me know.

-k

Keith Garner at MMS next week

Just a reminder that I will be at the Minnesota Management Summit (MMS) next week.

For the most part I’m excited about meeting up with ya all, learning about the state of the industry, and new products/features coming out. :^).

See you at the Mall of America!

 

MDT UberBug – More bugs from Johan

Some reminders of other MDT UberBugs out there.

Johan Arwidmark has found been following up with the MDT team on a couple of bugs:

LiteTouch

Issue #3 Editing Unattend.xml via WSIM breaks the deployment

Turns out that if you have an encoded administrator password in your Unattend.xml file (not recommended), then MDT 2013 Update 1 may not reset the <PlainText>False</PlainText> back to True.  This can cause a break during Windows Setup.  This may have something to do with a change in the ADK from MSXML3 to MSXML6. Microsoft is investigating.

ZeroTouch

Issue #2 ConfigMgr deployments displays “Can not find script file “X:\LTIBootstrap.ini”.” and tries Auto logon when

More errors with MSXML3 to MSXML6

Issue #3 The new disk handling logic that was supposed to remove the need for setting OSDPreserveDriveLetter only works for uEFI 

Sadly, I forgot what OSDPreserveDriveLetter was about, so I had to do an internet search. Oh yea, I have a blog post about that. But Frank wrote a better one.

 

Thanks Johan!

MDT UberBug06 – Having two recovery partitions is more secure

Getting some questions lately about recovery partitions in MDT LiteTouch, and yes, they are broken too.

ZTIDiskPart.wsf will automatically create hidden System partitions when you install the OS, this is typically 499MB and is at the start of the disk. In addition, MDT can also create a “Recovery” partition for the WinRE recovery system.

There are several things that are broken about this model, and I have filed several bugs against MDT to have these fixed.

However in MDT 2013 we can see that things have changed, someone noticed that there is an extra “recovery” partition on uEFI machines! Why is that?

Turns out that even tough MDT already creates a Recovery partition on uEFI scenarios, MDT 2013 Update 1 added a 2nd recovery partition, that is never used, and is not marked as “Hidden” for uEFI, so it’s quite confusing.

Additionally, I dislike the use of modifying the primary partition scheme and making the main partition 99%.

My fix is to convert the client.xml task sequence template back to the old MDT 2013 style:

from this:

<defaultVarList>
  <variable name="OSDDiskIndex" property="DiskIndex">0</variable>
  <variable name="OSDPartitions0Type" property="Partitions0Type">Primary</variable>
  <variable name="OSDPartitions0FileSystem" property="Partitions0FileSystem">NTFS</variable>
  <variable name="OSDPartitions0Bootable" property="Partitions0Bootable">True</variable>
  <variable name="OSDPartitions0QuickFormat" property="Partitions0QuickFormat">True</variable>
  <variable name="OSDPartitions0VolumeName" property="Partitions0VolumeName">OSDisk</variable>
  <variable name="OSDPartitions0Size" property="Partitions0Size">99</variable>
  <variable name="OSDPartitions0SizeUnits" property="Partitions0SizeUnits">%</variable>
  <variable name="OSDPartitions0VolumeLetterVariable" property="Partitions0VolumeLetterVariable">OSDisk</variable>
  <variable name="OSDPartitions1Type" property="Partitions1Type">Primary</variable>
  <variable name="OSDPartitions1FileSystem" property="Partitions1FileSystem">NTFS</variable>
  <variable name="OSDPartitions1Bootable" property="Partitions1Bootable">False</variable>
  <variable name="OSDPartitions1QuickFormat" property="Partitions1QuickFormat">True</variable>
  <variable name="OSDPartitions1VolumeName" property="Partitions1VolumeName">Recovery</variable>
  <variable name="OSDPartitions1Size" property="Partitions1Size">100</variable>
  <variable name="OSDPartitions1SizeUnits" property="Partitions1SizeUnits">%</variable> 
  <variable name="OSDPartitions1VolumeLetterVariable" property="Partitions1VolumeLetterVariable"></variable>
  <variable name="OSDDiskPartitions1Type" property="OSDDiskPartitions1Type">Recovery</variable>
  <variable name="OSDPartitions" property="Partitions">2</variable>     
  <variable name="OSDPartitionStyle" property="PartitionStyle">MBR</variable>
</defaultVarList>

Back to the MDT 2013 style:

<defaultVarList>
  <variable name="OSDDiskIndex" property="DiskIndex">0</variable>
  <variable name="OSDPartitions0Type" property="Partitions0Type">Primary</variable>
  <variable name="OSDPartitions0FileSystem" property="Partitions0FileSystem">NTFS</variable>
  <variable name="OSDPartitions0Bootable" property="Partitions0Bootable">True</variable>
  <variable name="OSDPartitions0QuickFormat" property="Partitions0QuickFormat">True</variable>
  <variable name="OSDPartitions0VolumeName" property="Partitions0VolumeName">OSDisk</variable>
  <variable name="OSDPartitions0Size" property="Partitions0Size">100</variable>
  <variable name="OSDPartitions0SizeUnits" property="Partitions0SizeUnits">%</variable>
  <variable name="OSDPartitions0VolumeLetterVariable" property="Partitions0VolumeLetterVariable">OSDisk</variable>
  <variable name="OSDPartitions" property="Partitions">1</variable>
  <variable name="OSDPartitionStyle" property="PartitionStyle">MBR</variable>
</defaultVarList>

I have yet to file a bug on this issue on connect, as the connect web site is broken again today.

-k