0
votes

So I am using this Powershell script: Set-RunOnce https://www.powershellgallery.com/packages/WindowsImageConverter/1.0/Content/Set-RunOnce.ps1

When I put the driveletter hardcoded in (E:\ServerInstall.ps1) it works like a charm. But I want to be sure this script can run from any drive letter the USB gets plugged into.

How can I get this changing drive letter in the registry?

I first tried it with -ExecutionPolicy Bypass, but that didn't change much either.

I also tried this:

$getusb = Get-WmiObject Win32_Volume -Filter "DriveType='2'" . .\Set-RunOnce.ps1 Set-RunOnce -Command

'%systemroot%\System32\WindowsPowerShell\v1.0\powershell.exe ` -ExecutionPolicy Unrestricted -File $getusb.Name\ServerInstall.ps1'

--> $getusb.Name\ServerInstall.ps1 ended being hardcoded in the registry, but it didn't know what $getusb.name was, so the script didn't launch.

. .\Set-RunOnce.ps1
Set-RunOnce -Command '%systemroot%\System32\WindowsPowerShell\v1.0\powershell.exe `
-ExecutionPolicy Unrestricted -File (wmic logicaldisk where drivetype=2)
ServerInstall.ps1'
1
Are you wanting to cause something to run each time the USB device is plugged into the machine?lit
You are not showing us what the ServerInstall.ps1 script does. You should perform the (wmic logicaldisk where drivetype=2) stuff in there and not put it in as part of the commandline. See the example on powershellgallery.com/packages/WindowsImageConverter/1.0/…Theo
Use "$($getusb.DriveLetter)\ServerInstall.ps1" instead of $getusb.Name\ServerInstall.ps1. Also consider that $getusb could be an array if more USB disks are plugged in…JosefZ
Why is the question tagged with cmd which is the Windows command processor used for processing Windows batch files. cmd.exe cannot execute PowerShell commands. PowerShell.exe is a completely different script interpreter. On using a batch file to run PowerShell.exe on double clicking on batch file on USB drive it would be possible to pass the drive of storage location of batch file as argument to PowerShell with %~d0 which expands on execution to drive letter and colon. Run in a cmd window call /? for help. Argument 0 is always the batch file itself.Mofi
@Mofi once it is in the registry it uses the cmd code, and not powershell code. Once I run it it gets hardcoded in the registry, and it stays "$($getusb.DriveLetter)\ServerInstall.ps1", it doesn't get a drive letterLaetitia

1 Answers

0
votes

The Set-RunOnce function is really easy to understand and simple to adjust.
I would suggest creating a derived function of your own to do what you want and use that instead:

function Set-RunOnceForUSB {
    # get the driveletter from WMI for the first (possibly only) USB disk
    $firstUSB   = @(Get-WmiObject -Class Win32_LogicalDisk | Where-Object {$_.DriveType -eq 2} | Select-Object -ExpandProperty DeviceID)[0]
    # or use:
    # $firstUSB = @(Get-WmiObject Win32_Volume -Filter "DriveType='2'" | Select-Object -ExpandProperty DriveLetter)[0]

    # combine that with the name of your script file to create a complete path
    $scriptPath = Join-Path -Path $firstUSB -ChildPath 'ServerInstall.ps1'

    # create the command string. use double-quotes so the variable $scriptPath gets expanded
    $command = "%systemroot%\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Unrestricted -File $scriptPath"

    # next, add this to the registry same as the original Set-RunOnce function does
    if (-not ((Get-Item -Path HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce).Run )) {
        New-ItemProperty -Path 'HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce' -Name 'Run' -Value $command -PropertyType ExpandString
    }
    else {
        Set-ItemProperty -Path 'HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce' -Name 'Run' -Value $command -PropertyType ExpandString
    }
}