That won't work in our env: we have hundreds of drives to build monthly
We'll stick with what I have. I'm going to leave the second question to rest for now.
Merry Christmas!
Multi USB OSDBootMedia Solution
Forum rules
Do not post any licensing information in this forum.
Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
Do not post any licensing information in this forum.
Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
Re: Multi USB OSDBootMedia Solution
Sorry but Windows isn't designed to do what you ask. ALl drives are virtualized, and the USB bus is plug-n-play which makes its behavior unpredictable. Any drive can be inserted in any oport and teh ris no way to know which one was inserted last or if that drive is the one the user wants to use.
If you absolutely know which port the drive is always going to be plugged into then just use the port addrews to assume it is the one the user wants to prepare. Watch out as the user can pick the wrong port if they are close together. and one already has a drive. You may prepare an important data drive.
The USB ports are not fixed from the user's perspective and different PCs will number them differently. The OS can assign ports differently even between boots and especially if there are other storage devices internal or external, that are already connected. Most new PCs mount internal storage like DVDs on the USB internally and a DVD may respond in any order to the boot scan for devices. Any time a patch is installed and any time the OS restarts it may choose to rescan the ports and receive them in a different order. Virtualization of hardware makes predictability impossible.
One approach that I have used is to prompt the user to remove the drive and re-insert it while maintaining a WMI event that detects new devices but even this method is not foolproof.
If you absolutely know which port the drive is always going to be plugged into then just use the port addrews to assume it is the one the user wants to prepare. Watch out as the user can pick the wrong port if they are close together. and one already has a drive. You may prepare an important data drive.
The USB ports are not fixed from the user's perspective and different PCs will number them differently. The OS can assign ports differently even between boots and especially if there are other storage devices internal or external, that are already connected. Most new PCs mount internal storage like DVDs on the USB internally and a DVD may respond in any order to the boot scan for devices. Any time a patch is installed and any time the OS restarts it may choose to rescan the ports and receive them in a different order. Virtualization of hardware makes predictability impossible.
One approach that I have used is to prompt the user to remove the drive and re-insert it while maintaining a WMI event that detects new devices but even this method is not foolproof.
Re: Multi USB OSDBootMedia Solution
What? I usually enjoy your breakdowns but this one isn't close.
you stated 'One approach that I have used is to prompt the user to remove the drive and re-insert it while maintaining a WMI event that detects new devices but even this method is not foolproof.'
Why? whats wrong with the code I posted? I've done a suitable number of test with this code, I just have no way to validate the drive letter assigned - again, not a requirement but should be way easier than MS is making it
you stated 'One approach that I have used is to prompt the user to remove the drive and re-insert it while maintaining a WMI event that detects new devices but even this method is not foolproof.'
Why? whats wrong with the code I posted? I've done a suitable number of test with this code, I just have no way to validate the drive letter assigned - again, not a requirement but should be way easier than MS is making it
- $USBs = Get-Disk | Select-Object -Property * | Where-Object {$_.BusType -eq 'USB' -and $_.Size -gt 0} | Select-Object DiskNumber, FriendlyName, @{Name="Size (GB)"; Expression={[math]::round($_.size/1GB, 1)}}, @{Name="Serial"; Expression={ $_.Path.Split('#')[2].replace('&0','').toupper() }} | sort DiskNumber
- $MatchSerial = (gwmi Win32_USBControllerDevice |%{[wmi]($_.Dependent)} | Where-Object {($_.Description -like '*mass*')} | Select-Object -ExpandProperty Path | ForEach-Object { Split-Path $_ -Leaf}) -replace('"','')
- #Build Drives
- #robocopy \\server\OSDBootMedia\Media C:\Windows\TechDir\TempOSDBuild /MIR /mt:128
- $USBs |Where-Object {$_.Serial -in $MatchSerial}| ForEach-Object {
- $USB = $_
- }
Re: Multi USB OSDBootMedia Solution
If you know the event, then you know the device path. You can convert the device path to the virtual device (PNPDevice) then obtain the drive letter also known as the "virtual device id". A term invented by IBM and usually referred to as the LUN or "Logical Unit Number" which in the PC world is a letter. Don't ask me why. IBM liked to try to sabotage small computing devices which is why the PC spec is so screwy.
PowerShell leverages this because teh PC spec doesn't preclude using any string to assign a LUN so you can mount a drive in PowerShell and give it a long string name like "MYDEVICE1" or "MYFUNNYPICTURES". Unfortunately, the OS only allows single letters A-Z and ignores PS extended device LUNs for storage devices but COM and LPT are pre-defined and accepted LUNs which are extended by numbers COM1, COM2, COM123 all are legitimate. As I noted the PC spec is totally inconsistent. All primitive file APIs see COM and LPT LUNs as openable and readable devices. Add USB spec and the whole thing becomes virtualized and then virtualized again. This is to adapt the USB spec to the industry standard and then to adapt it to the PC standard and the inconsistent Windows OS specs.
History is what always defeats us but only because we fail to learn the history of things. The assumption is that the top-level description is explanation enough until you add all new industry specifications.
Note that WMI is a dead item as CIM and CIMOM are the new standards.
Back to identifying drive letters. Drive letters are assigned at the OS/Session level. Windows device ids are assigned at the virtualization layer and assigned to the industry USB device path level in this case called the PNP subsystem or someth9ing like that. This forces us to have to acquire both table entries and use the "label" which shows up as the "Description" in the Get-PsDrive objects for the "Filesystem" device type. The data for the new device is in the event object passed by the event and comes as "baggage" attached as an arbitrary data object which can be inspected in the debugger to find the property that tells you the device label and the even object should also have the PNP device path.
PowerShell leverages this because teh PC spec doesn't preclude using any string to assign a LUN so you can mount a drive in PowerShell and give it a long string name like "MYDEVICE1" or "MYFUNNYPICTURES". Unfortunately, the OS only allows single letters A-Z and ignores PS extended device LUNs for storage devices but COM and LPT are pre-defined and accepted LUNs which are extended by numbers COM1, COM2, COM123 all are legitimate. As I noted the PC spec is totally inconsistent. All primitive file APIs see COM and LPT LUNs as openable and readable devices. Add USB spec and the whole thing becomes virtualized and then virtualized again. This is to adapt the USB spec to the industry standard and then to adapt it to the PC standard and the inconsistent Windows OS specs.
History is what always defeats us but only because we fail to learn the history of things. The assumption is that the top-level description is explanation enough until you add all new industry specifications.
Note that WMI is a dead item as CIM and CIMOM are the new standards.
Back to identifying drive letters. Drive letters are assigned at the OS/Session level. Windows device ids are assigned at the virtualization layer and assigned to the industry USB device path level in this case called the PNP subsystem or someth9ing like that. This forces us to have to acquire both table entries and use the "label" which shows up as the "Description" in the Get-PsDrive objects for the "Filesystem" device type. The data for the new device is in the event object passed by the event and comes as "baggage" attached as an arbitrary data object which can be inspected in the debugger to find the property that tells you the device label and the even object should also have the PNP device path.
Re: Multi USB OSDBootMedia Solution
Here. I broke my own rules and grabbed this detail.
https://docs.microsoft.com/en-us/window ... hangeevent
This is where the events start that give access to the new PNP device at the Win32 level which occurs before the PNP and USB allocations. The full event object should contain the identifying information.
Here is an example of how to use an event generated by a PNP device:
https://stackoverflow.com/questions/536 ... on-windows
https://docs.microsoft.com/en-us/window ... hangeevent
This is where the events start that give access to the new PNP device at the Win32 level which occurs before the PNP and USB allocations. The full event object should contain the identifying information.
Here is an example of how to use an event generated by a PNP device:
https://stackoverflow.com/questions/536 ... on-windows
Re: Multi USB OSDBootMedia Solution
Rules are meant to be broken, right?
Thanks for this and gives me reading for the day.
Thanks for this and gives me reading for the day.
Re: Multi USB OSDBootMedia Solution
No rules need to be broken. Rules need to be understood. You can't break rules that are fixed in the hardware and driver subsystem. That would constitute hacking which is never allowed in commercial code.
I looked closer at the example I posted and saw it was misleading and incomplete, so I did a quick rewrite as a persistent example. I also object to creating unneeded variables and spreading code all over the script. Event code can all be placed in teh hash when used. This is pone stop shopping a way more understandable and maintainable. Code style is not for "prettiness" It serves a technical and engineering purpose. All of these debates were settled more that 30 years ago, but non formally trained coders keep writing rules that were inspected and abandoned decades ago for good technical reasons.
You can break any rules you want as there are no code police, but I strongly recommend against breaking rules without a deep technical understanding of the system beyond just how to write simple PowerShell code. It will always end up getting you into trouble with code and you will not be able to see why. This is a side-effect of using bad concepts that we all suffer from. I have done it to myself in the past.
I looked closer at the example I posted and saw it was misleading and incomplete, so I did a quick rewrite as a persistent example. I also object to creating unneeded variables and spreading code all over the script. Event code can all be placed in teh hash when used. This is pone stop shopping a way more understandable and maintainable. Code style is not for "prettiness" It serves a technical and engineering purpose. All of these debates were settled more that 30 years ago, but non formally trained coders keep writing rules that were inspected and abandoned decades ago for good technical reasons.
You can break any rules you want as there are no code police, but I strongly recommend against breaking rules without a deep technical understanding of the system beyond just how to write simple PowerShell code. It will always end up getting you into trouble with code and you will not be able to see why. This is a side-effect of using bad concepts that we all suffer from. I have done it to myself in the past.
- $addEventArgs = @{
- Query = 'SELECT * FROM __instancecreationevent WITHIN 5 WHERE targetinstance isa "Win32_PnPEntity"'
- SourceIdentifier = 'WMI.PnpAddEvent'
- SupportEvent = $true
- Action = {
- $global:PnpAddEvent = $EventArgs.NewEvent.TargetInstance
- Write-Host "PNPEvent: Plugged In`nCaption: $($PnpAddEvent.Caption)" -ForegroundColor Green
- Write-Host "PNPDeviceID: $($PnpAddEvent.PNPDeviceID)" -ForegroundColor Green
- }
- }
- $removeEventArgs = @{
- Query = 'SELECT * FROM __instancedeletionevent WITHIN 5 WHERE targetinstance isa "Win32_PnPEntity"'
- SourceIdentifier = 'WMI.PnpRemoveEvent'
- SupportEvent = $true
- Action = {
- $global:PnpRemoveEvent = $EventArgs.NewEvent.TargetInstance
- Write-Host "PNPEvent: Unplugged Caption: $($PnpRemoveEvent.Caption)" -ForegroundColor Yellow
- Write-Host "PNPDeviceID: $($PnpRemoveEvent.PNPDeviceID)" -ForegroundColor Yellow
- }
- }
- Register-WmiEvent @addEventArgs
- Register-WmiEvent @removeEventArgs
- # The two global variables are available anywhere in the script.
- # Wait for the event to be reported and then type the correct variable name
- # and you will have the data needed as the "TargetInstance object.
- # it would be best to remove all code in the action block except for the assignment of the global
- # or assign the form control from the event code and use a "TextChanged" event in the form to proceed with processing.
- -
Re: Multi USB OSDBootMedia Solution
There is a method that allows assigning the event to the form as an added from or control event. Unfortunately, I can't remember how to do that. If it comes to me, I will post it.
Re: Multi USB OSDBootMedia Solution
Thee rules was a joke
I don't dismiss anything you say. We're extremely lucky to have your wisdom.
I don't dismiss anything you say. We're extremely lucky to have your wisdom.
Re: Multi USB OSDBootMedia Solution
Thank you for that. I try tp be helpful when possible.
Not so much wisdom as it is just a lot of experience and a lot of work studying what is known about science, engineering and coded systems. I was lucky to have been given a book by a guy named Yourdon who had things pretty well worked out in about 1981 that has become fundamental to modern systems automation.
Also, I think true wisdom comes from failure as much or more than success and I have succeeded more than I have failed. I have listened to others, and I think that helped my successes, but the failures have also helped.
As the great bard said:
Some speak of the future,
My love she speaks softly,
She knows there's no success like failure
And that failure's no success at all.
Now that is what I call wisdom. I could never have said that.
Not so much wisdom as it is just a lot of experience and a lot of work studying what is known about science, engineering and coded systems. I was lucky to have been given a book by a guy named Yourdon who had things pretty well worked out in about 1981 that has become fundamental to modern systems automation.
Also, I think true wisdom comes from failure as much or more than success and I have succeeded more than I have failed. I have listened to others, and I think that helped my successes, but the failures have also helped.
As the great bard said:
Some speak of the future,
My love she speaks softly,
She knows there's no success like failure
And that failure's no success at all.
Now that is what I call wisdom. I could never have said that.