Welcome to the community forums for Theopenem. All responses are provided by other users that wish to help out. Theopenem will not respond to these posts. If you require more assistance than what the community can provide, we offer various paid support options.


  • Microsoft has this thing called Storage Spaces, I don't know the history but it's something akin to RAID, but also like Intel RST. As a result of the later, on Microsoft systems apparently sometimes the factory configuration uses Storage Spaces.

    So I have a Surface Laptop 2 on my desk, I imaged it like I image everything and it came up with a 512GB SSD; but also a second blank 512GB SSD. Looking at images of the motherboard what's happening here is the 1TB configuration uses two all-in-one SSD chips, each 512GB, each literally a distinct SSD, and they're supposed to be pooled under a single Storage Space to appear as one.

    It's possible to configure these Spaces in powershell but I can't imagine there's any reasonable way to detect that this should be done, so configuration regarding pools would need to be added to the image profile and I'm unclear if the image needs to be built for Spaces or if windows will adapt. This may also require considering the physical disks differently while partitioning and formatting the drives.

    I'm going to be looking into patching this into the core scripts soon


  • I've put together how to create the pools, this needs a lot of work but the basics are there

    $matchedDiskSets = Get-PhysicalDisk | Group-Object 'FriendlyName' | Where-Object {$_.Count -gt 1}
    # assuming matched disks should always be pooled, this should be a configuration recieved from the server
    if ($matchedDiskSets -gt 0) {
    
    
        <# assuming all existing pools are bad
           should try to identify good pools
           to associate disks with pools:
           $pools = Get-StoragePool -isPrimordial $false -ErrorAction SilentlyContinue
           $disksInPool = $pools | foreach { get-physicalDisks -StoragePool $_ }
        #>
        
        Get-StoragePool -isPrimordial $false -ErrorAction SilentlyContinue | Remove-StoragePool
        # ignoring secondary pools for now
        $matchedDiskSets[0].Group | ForEach-Object {
            Clear-Disk `
                -UniqueID $_.UniqueID `
                -RemoveOEM `
                -RemoveData `
                -Confirm:$false `
                -ErrorAction SilentlyContinue
            }
        $matchedDiskSets[0].Group | Reset-PhysicalDisk
    
        # create new pool and virtualdisk, I picked WindowsPool and WindowsDisk arbitrarily
        New-StoragePool `
            -FriendlyName "WindowsPool" `
            -StorageSubsystemFriendlyName "Windows Storage*" `
            -PhysicalDisks $matchedDiskSets[0].Group `
            -ResiliencySetting Simple `
            | New-VirtualDisk -FriendlyName "WindowsDisk" -UseMaximum
    
    }
    

    The critical problem resulting from this is that the virtual disk is not going to be disk 1. It seems to vary, this is from a log from a previous image attempt with a manually created pool.

        ** Starting Image Download For Hard Drive 3 Partition 3
        
        [ERROR] Error reading 208 bytes from fd 0 (err=109): The pipe has been ended
        
        [ERROR] "[fd 0]": Error reading header: Broken pipe
        ERROR: Exiting with error code 50:
        Could not read data from a file.
    

    The unit I'm working with presently made the virtual disk be disk 2 to start, and then disk 3 after a reboot.

    PS X:\Windows\System32> get-physicaldisk
    
    Number FriendlyName
    ------ ------------
    1      Skhynix BC501 NVMe 512GB
    0      Skhynix BC501 NVMe 512GB
    
    PS X:\Windows\System32> get-disk
    
    Number    Friendly Name
    --------- ----------------
    2         WindowsDisk
    
    

    and in wie_deploy.ps1 it's assumed that machine-side disks will relate 1-to-1 with disks in the image

    line 326

    $udpProc=$(Start-Process cmd "/c curl.exe $script:curlOptions -H Authorization:$script:userTokenEncoded --data ""profileId=$profile_id&hdNumber=$($hardDrive.Number)&fileName=part$wimSource.winpe.wim"" ${script:web}GetImagingFile | wimapply - 1 C: 2>>$clientLog > x:\wim.progress" -NoNewWindow -PassThru)

    Which makes sense until pools are involved and there are gaps in the index of logical disks. This is the next thing I'm going to run down, not sure how I'm going to map the two indexes.

    edit: the windows 10 installer can't see this disk so I'm probably missing a little detail somewhere.