In this article, I will demonstrate how to use Microsoft Deployment Toolkit (MDT) and PowerShell to create a reusable in-place upgrade process for domain-joined computers.

This is a completely automated process. Thus, no end-user interaction is necessary, and it can take place on any remote computer. Although I have not tested it specifically, theoretically this function should be able to upgrade hundreds of workstations simultaneously with the proper computing in place.

While adoption of Windows 10 for businesses has been growing, many workstations still run Windows 7 or Windows 8. For mass in-place upgrades, System Center Configuration Manager (SCCM) is the most widely used option as it allows administrators to push out the upgrade easily. For organizations that do not use SCCM, such as small to medium-sized businesses, there are other viable options, notably using MDT along with PowerShell.

Please note this solution will not be a fit for every organization. It requires the use of the Remote Desktop Protocol (RDP) on each machine to launch the upgrade process, and it is widely known that RDP is not entirely secure. The need for using RDP is due to the MDT upgrade process requiring a user logged on to the computer to launch the litetouch.vbs file. With that said, there are ways to reduce the security hole by using public key infrastructure (PKI) and enabling RDP only during the upgrade process. I also recommend changing the password on the account connecting via RDP immediately after the upgrade is complete.

Setting up MDT ^

Before we can begin deploying the in-place upgrade, we need to setup an MDT deployment share including importing the Windows 10 media and creating a new upgrade task sequence. I will not go into how to do this since this Microsoft blog already covers it.

The setup of MDT for the in-place upgrade is trivial, but to automate the role of MDT in this process fully, we must alter the bootstrap.ini and customsettings.ini files on the MDT share.

We need to edit bootstrap.ini to skip the welcome screen and supply credentials to the MDT share:

[Settings]
Priority=Default

[Default]
DeployRoot=MDTShareRoot
SkipBDDWelcome=YES
UserDomain=DOMAIN
UserID=User
UserPassword=Password

In the customsettings.ini file we will need to configure MDT monitoring, skip all of the screens, and most importantly specify the task sequence to run, which should match your Windows 10 in-place upgrade task sequence.

[Settings]
Priority=Default
Properties=MyCustomProperty

[Default]
OSInstall=Y
SkipCapture=NO
SkipAdminPassword=YES
SkipProductKey=YES
SkipComputerBackup=NO
SkipBitLocker=YES
EventService=http://mdtserver:9800
FinishAction=REBOOT
ApplyGPOPack=NO
SkipLocaleSelection=YES
SkipAppsOnUpgrade=YES
SkipDomainMembership=YES
SkipComputerName=YES
SkipTimeZone=YES
TimeZoneName=Eastern Standard Time
TimeZone=035
SkipSummary=YES
SkipFinalSummary=YES
SkipUserData=YES
SkipTaskSequence=YES
TaskSequenceID=WIN10-INPLACE
BuildID=WIN10-INPLACE

Overview of the Invoke-Win10Upgrade function ^

Now that MDT is ready, PowerShell will be orchestrating the remote in-place upgrades. The main process of the function is as follows:

  • Ping each computer using a PowerShell workflow to ensure it is online.
  • Restart all computers to ensure no users are logged on to the console.
  • Create a scheduled task to launch litetouch.vbs when a specified user logs on.
  • Enable RDP on each workstation.
  • Launch an RDP session to each computer, which will launch the upgrade MDT process.
  • Remove the scheduled task since it will be no longer be needed.
  • Monitor the MDT upgrade process for each remote computer until all are complete.
  • Disable RDP on each workstation.

Stepping through Invoke-Win10Upgrade ^

Now let's step through some code in this function to understand better what is happening.

The workflow Test-Ping can sift through the computers provided in the $ComputerName parameter to ensure they are online. If it cannot ping computers, it will not attempt an upgrade on them.

workflow Test-Ping
        {
            param(
                [Parameter(Mandatory=$true)]
                [string[]]$Computers
            )
                foreach -parallel -throttlelimit 150 ($Computer in $Computers)
                {
                    if (Test-Connection -Count 1 $Computer -Quiet -ErrorAction SilentlyContinue)
                    {
                        $Computer
                    }
                    else
                    {
                        Write-Warning -Message "$Computer not online"
                    }
                }
         }
        $ComputerName = Test-Ping -Computers $ComputerName

Next, Restart-Computer reboots all computers. The command waits for PowerShell to be accessible before continuing. This ensures no users are logged on to the console and also gets the machines in a clean state, ready for upgrade.

Restart-Computer -ComputerName $ComputerName -Force -Wait -For powershell -Timeout 600

Here, we use Invoke-Command to create a scheduled task to launch litetouch.vbs upon the logon of the account specified in the $Credential parameter.

$STUserName = $Credential.UserName

        Invoke-Command -ComputerName $ComputerName -ArgumentList {$STUsername,$MDTLiteTouchPath} -ScriptBlock {
            schtasks.exe /ru $Using:STUserName /create /tn 'Upgrade to Windows 10' /tr "powershell -command Start-Process -FilePath cscript -ArgumentList $Using:MDTLiteTouchPath" /sc onlogon /RL HIGHEST /f /IT /DELAY 0000:30

The Connect-RDP workflow launches an RDP connection to each computer, which will then launch litetouch.vbs via the scheduled task. Due the workflow using ‑parallel, these RDP connections will happen simultaneously with a default throttle of 150 workstations. Remember there will be an RDP process for each computer you are upgrading. Thus, you should have a certain amount of CPU and memory on your local machine depending on how many workstations you want to upgrade simultaneously.

workflow Connect-RDP
        {
            param(
            [Parameter(Mandatory=$true)]
            [string[]]$RDPComputers,
            [Parameter(Mandatory=$true)]
            [pscredential]$RDPCredential
            )
            $RDPUser = $RDPCredential.UserName
            $RDPPassword = $RDPCredential.GetNetworkCredential().Password

            foreach -parallel -Throttlelimit 150 ($RDPComputer in $RDPComputers)
            {
                cmdkey.exe /generic:TERMSRV/$RDPComputer /user:$RDPUser /pass:$RDPPassword
                Start-Process -FilePath mstsc.exe -ArgumentList "/v $RDPComputer"
            }
        }
        #Put start time in variable for MDT monitoring
        $StartTime =  (Get-Date).ToUniversalTime()
        Connect-RDP -RDPComputers $ComputerName -RDPCredential $Credential

After launching RDP, Invoke-Command removes the scheduled task created previously.

Invoke-Command -ComputerName $ComputerName -ScriptBlock {
    schtasks.exe /Delete /TN 'Upgrade to Windows 10' /F
}

Now that all computers are in the process of upgrading, we monitor our MDT share to see the status. The status will update every 60 seconds in your console until all upgrades are done.

try 
        {
            $Results = Invoke-Command -ComputerName $MDTComputerName -ArgumentList $MDTRoot,$StartTime -ErrorAction Stop -ScriptBlock {
                Add-PSSnapin Microsoft.BDD.PSSnapIn | Out-null
                New-PSDrive -Name "DS001" -PSProvider "MDTProvider" -Root $Using:MDTRoot | out-null
                Get-MDTMonitorData -Path DS001: | Where-Object {$_.PercentComplete -ne '100' -and $_.StartTime -gt $Using:StartTime} | Select-Object name,percentcomplete,errors,starttime | Sort-Object -Property starttime -Descending | Format-Table -AutoSize }
            if (!$Results)
            {
                Write-Warning -Message 'No MDT Monitoring data found. Investigate and press enter to continue'
                Read-Host "Press enter to continue"
            }
        }
        catch 
        {
            Write-Error $_
            Read-Host "Press enter to continue" 
        }

        While ($AllDone -ne '1')
        {
            $Results = Invoke-Command -ComputerName $MDTComputerName -ArgumentList $MDTRoot,$StartTime -ErrorAction Stop -ScriptBlock {
                Add-PSSnapin Microsoft.BDD.PSSnapIn | Out-null
                New-PSDrive -Name "DS001" -PSProvider "MDTProvider" -Root $Using:MDTRoot | Out-null
                Get-MDTMonitorData -Path DS001: | Where-Object {$_.PercentComplete -ne '100' -and $_.StartTime -gt $Using:StartTime} | Select-Object name,percentcomplete,errors,starttime | Sort-Object -Property starttime -Descending | Format-Table -AutoSize }
            if ($Results)
            {
                  Invoke-Command -ComputerName $MDTComputerName -ArgumentList $MDTRoot,$StartTime -ErrorAction Stop -ScriptBlock {
                      Add-PSSnapin Microsoft.BDD.PSSnapIn | Out-null
                      New-PSDrive -Name "DS001" -PSProvider "MDTProvider" -Root $Using:MDTRoot | Out-null 
                      Get-MDTMonitorData -Path DS001: | Where-Object {$_.StartTime -gt $Using:StartTime} | Select-Object name,percentcomplete,errors,starttime | Sort-Object -Property starttime -Descending | Format-Table -Property @{Expression={$_.StartTime.ToLocalTime()};Label="StartTime"},name,percentcomplete,errors -AutoSize }
            }
            else 
            {
                $AllDone = '1'
                Write-Warning -Message 'Deployment Complete'
            }
            Start-Sleep -Seconds 60
        }

Invoke-Win10Ugrade example ^

In this example I have machines Test-1 and Test-2 that I want to upgrade. For the parameters, I need to specify the MDT server hostname, MDT litetouch, the computers to upgrade, and the credential to use.

C:\> Invoke-Windows10Upgrade -ComputerName Test-1,Test-2 ‑Credential $Credential ‑MDTLiteTouchPath '\\MDTServer\WIN10UPGRADES\Scripts\LiteTouch.vbs' ‑MDTRoot 'E:\MDT' ‑MDTComputerName MDTServer ‑AllowRDP ‑DisableRDP
Using Invoke Win10Upgrade

Using Invoke Win10Upgrade

Code for Invoke-Win10Upgrade ^

Note you can also download the latest version from my GitHub repository:

Subscribe to 4sysops newsletter!

#requires -Version 4
#requires -RunAsAdministrator
function Invoke-Windows10Upgrade {
    [CmdletBinding()]
    param
	(
	[Parameter(Mandatory=$true)]
	[String[]]$ComputerName,
        [Parameter(Mandatory=$true)]
        [PSCredential]$Credential,
        [Parameter(Mandatory=$true)]
        [String]$MDTLiteTouchPath,
        [Parameter(Mandatory=$true)]
        [String]$MDTComputerName,
        [Parameter(Mandatory=$true)]
        [String]$MDTRoot,
        [Parameter(Mandatory=$False)]
        [Switch]$AllowRDP,
        [Parameter(Mandatory=$False)]
        [Switch]$DisableRDP 
	)
    process
    {
        #Test to ensure computers are online and return only those that can be pinged
        workflow Test-Ping 
        {
            param( 
                [Parameter(Mandatory=$true)] 
                [string[]]$Computers
            )
                foreach -parallel -throttlelimit 150 ($Computer in $Computers) 
                {
                    if (Test-Connection -Count 1 $Computer -Quiet -ErrorAction SilentlyContinue) 
                    {    
                        $Computer
                    }
                    else
                    {
                        Write-Warning -Message "$Computer not online"
                    }
                }
         }
        $ComputerName = Test-Ping -Computers $ComputerName 
        if (!$ComputerName)
        {
            Write-Warning -Message 'No computers are online. Exiting.'
            Break
        }

        #Restart all computers
        Restart-Computer -ComputerName $ComputerName -Force -Wait -For powershell -Timeout 600

        #Create Scheduled task on remote computers
        $STUserName = $Credential.UserName

        #Set scheduled task to launch litetouch.vbs
        Invoke-Command -ComputerName $ComputerName -ArgumentList {$STUsername,$MDTLiteTouchPath} -ScriptBlock {
            schtasks.exe /ru $Using:STUserName /create /tn 'Upgrade to Windows 10' /tr "powershell -command Start-Process -FilePath cscript -ArgumentList $Using:MDTLiteTouchPath" /sc onlogon /RL HIGHEST /f /IT /DELAY 0000:30 
        } 
        
        #Allow RDP
        if ($AllowRDP)
        {
            Invoke-Command –Computername $ComputerName –ScriptBlock {
                Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Terminal Server" -Name "fDenyTSConnections" –Value 0
                Netsh advfirewall firewall set rule group=”remote desktop” new enable=yes }
        } 
        
        #RDP using workflow into all computers in $ComputerName
        workflow Connect-RDP
        {
            param(
            [Parameter(Mandatory=$true)]
            [string[]]$RDPComputers,
            [Parameter(Mandatory=$true)]
            [pscredential]$RDPCredential
            )
            $RDPUser = $RDPCredential.UserName
            $RDPPassword = $RDPCredential.GetNetworkCredential().Password
            
            foreach -parallel -Throttlelimit 150 ($RDPComputer in $RDPComputers)
            {
                cmdkey.exe /generic:TERMSRV/$RDPComputer /user:$RDPUser /pass:$RDPPassword
                Start-Process -FilePath mstsc.exe -ArgumentList "/v $RDPComputer" 
            }
        }

        #Put start time in variable for MDT monitoring
        $StartTime =  (Get-Date).ToUniversalTime()
        Connect-RDP -RDPComputers $ComputerName -RDPCredential $Credential 
        #Sleep to wait for litetouch to start
        Start-Sleep -seconds 300

        #Remove scheduled task
        Invoke-Command -ComputerName $ComputerName -ScriptBlock {
        schtasks.exe /Delete /TN 'Upgrade to Windows 10' /F  
        }

        #Monitor MDT results
        try 
        {
            $Results = Invoke-Command -ComputerName $MDTComputerName -ArgumentList $MDTRoot,$StartTime -ErrorAction Stop -ScriptBlock {
                Add-PSSnapin Microsoft.BDD.PSSnapIn | Out-null
                New-PSDrive -Name "DS001" -PSProvider "MDTProvider" -Root $Using:MDTRoot | out-null
                Get-MDTMonitorData -Path DS001: | Where-Object {$_.PercentComplete -ne '100' -and $_.StartTime -gt $Using:StartTime} | Select-Object name,percentcomplete,errors,starttime | Sort-Object -Property starttime -Descending | Format-Table -AutoSize }
            if (!$Results)
            {
                Write-Warning -Message 'No MDT Monitoring data found. Investigate and press enter to continue'
                Read-Host "Press enter to continue"
            }
        }
        catch 
        {
            Write-Error $_
            Read-Host "Press enter to continue" 
        }

        While ($AllDone -ne '1')
        {
            $Results = Invoke-Command -ComputerName $MDTComputerName -ArgumentList $MDTRoot,$StartTime -ErrorAction Stop -ScriptBlock {
                Add-PSSnapin Microsoft.BDD.PSSnapIn | Out-null
                New-PSDrive -Name "DS001" -PSProvider "MDTProvider" -Root $Using:MDTRoot | Out-null
                Get-MDTMonitorData -Path DS001: | Where-Object {$_.PercentComplete -ne '100' -and $_.StartTime -gt $Using:StartTime} | Select-Object name,percentcomplete,errors,starttime | Sort-Object -Property starttime -Descending | Format-Table -AutoSize }
            if ($Results)
            {
                  Invoke-Command -ComputerName $MDTComputerName -ArgumentList $MDTRoot,$StartTime -ErrorAction Stop -ScriptBlock {
                      Add-PSSnapin Microsoft.BDD.PSSnapIn | Out-null
                      New-PSDrive -Name "DS001" -PSProvider "MDTProvider" -Root $Using:MDTRoot | Out-null 
                      Get-MDTMonitorData -Path DS001: | Where-Object {$_.StartTime -gt $Using:StartTime} | Select-Object name,percentcomplete,errors,starttime | Sort-Object -Property starttime -Descending | Format-Table -Property @{Expression={$_.StartTime.ToLocalTime()};Label="StartTime"},name,percentcomplete,errors -AutoSize }
            }
            else 
            {
                $AllDone = '1'
                Write-Warning -Message 'Deployment Complete'
            }
            Start-Sleep -Seconds 60
        }

        #Disable RDP
        if ($DisableRDP)
        {
            Invoke-Command –Computername $ComputerName –ScriptBlock {
               Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Terminal Server" -Name "fDenyTSConnections" –Value 1
               Netsh advfirewall firewall set rule group=”remote desktop” new enable=no }
        }   
    }
}
avatar
36 Comments
  1. Sid 5 years ago

    Hello Dan
    I see you are using RDP to each endpoint to initiate the execution of litetouch.
    how would you change the process so that the litetouch could be executed by a 3rd party deployment tool like landesk?
    thanks

  2. Author
    Dan Franciscus 5 years ago

    Hard to say, I have never used landesk. The part that is tricky is that from what I understand, a user must be logged in via console or RDP in order to execute litetouch. I wanted to automate this so that there was no end user interaction required, so I opted for RDP and a scheduled task.

  3. Paul 5 years ago

    Hey Dan,

    Thanks for the script! This works great so far! I was just curious; am I able to set the MDTLiteTouchPath, MDTRoot & MDTComputer name within the script rather than needing to specify each time? This is probably more of a PS question than a question on your script but I’m trying to set this up for a client and want to make it as easy as possible (they are not PS savvy!). My preference is to set these variables in the script and just update when required.

    Thanks!

    • Author
      Dan Franciscus 5 years ago

      Absolutely, just edit it in the function parameters:

      [String]$MDTLiteTouchPath = ‘\\MDTServer\WIN10UPGRADE$\Scripts\LiteTouch.vbs’,
      [Parameter(Mandatory=$false)]
      [String]$MDTComputerName = ‘MDTServer’,
      [Parameter(Mandatory=$false)]
      [String]$MDTRoot = ‘E:\MDT’,

  4. Paul 5 years ago

    You’re a legend! Thanks much!

  5. Paul 5 years ago

    Hey Dan,

    Sorry to be a pest; I’m having some issues with the monitoring portion of your script, although I think it may be my MDT setup thats causing the problem. Everything works great as far as actually pushing out the update. However after that point, the script cannot seem to properly query my MDT monitoring service.

    I get this error first:

    Invoke-Windows10Upgrade : [] Connecting to remote server failed with the following error message
    : The WinRM client sent a request to an HTTP server and got a response saying the requested HTTP URL was not
    available. This is usually returned by a HTTP server that does not support the WS-Management protocol. For more
    information, see the about_Remote_Troubleshooting Help topic.
    At line:1 char:1
    + Invoke-Windows10Upgrade -ComputerName vmwin10mdttest -Credential $cre …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Invoke-Windows10Upgrade

    and then after hitting continue, I get this:

    [] Connecting to remote server failed with the following error message : The WinRM client sent a
    request to an HTTP server and got a response saying the requested HTTP URL was not available. This is usually returned
    by a HTTP server that does not support the WS-Management protocol. For more information, see the
    about_Remote_Troubleshooting Help topic.
    At C:\\automateMDTupgrade.psm1:137 char:13
    + $Results = Invoke-Command -ComputerName $MDTComputerName …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : OpenError: (String) [], PSRemotingTransportException
    + FullyQualifiedErrorId : URLNotAvailable,PSSessionStateBroken

    If I run the commands (line 117 – 120) manually, I don’t get any errors but I also don’t get any results. I can connect to the MDT monitoring pages as well.

    I can also connect to the server via WINRM locally and remotely.

    One thing of note; I do not have a MDT Monitoring service installed on my server. I have enabled/disabled monitoring several times and rebooted the server as well. I assume its working because the websites appear but maybe that is where my problem lies.

    Thanks

    • Author
      Dan Franciscus 5 years ago

      Are you able to test to see if the event service port is available from the server you are running the script from? http://MDTServer:9800. Are you able to remote into the MDT server as well from the server you are running the script from?

  6. Paul 5 years ago

    yessir. Status pages/service ports are available on the server and remotely. Same with WINRM. I can enter a PS session and run commands locally (through invoke-command) and from a remote system.

    • Author
      Dan Franciscus 5 years ago

      Hmm. Well I ran the script straight from Github, seems to work fine with my MDT so I don’t believe it is the script itself, could be wrong.

      I believe the problem has to do with the Invoke-Command. Doesn’t appear remoting is working for you. I do not think its the MDT service at all actually now that I look at the error.

       

  7. Author
    Dan Franciscus 5 years ago

    Are you running this function from the MDT server itself? Or from another server? Just trying to figure out why you are getting that.

  8. Paul 5 years ago

    I’m currently running it against the MDT server and it probably will be normally used this way by the client. They are not super savvy with Powershell so I’m doing my best to set up this server so they can run everything from it.

    • Author
      Dan Franciscus 5 years ago

      Just to be clear, you are running this script ON the MDT server? Meaning you login to the MDT server and then run this script on it?

      Just want to make sure we are on the same page because the function assumes you are running it from a server that is NOT the MDT server.

  9. Paul 5 years ago

    No thats exactly what is going on and what I was starting to look at yesterday. This script is and will be ran from the MDT server itself going forward. So I’m guessing I would need to update the script to remove the Invoke commands and instead just run them as if it was a normal script executing on the box? Sorry my PS skills are lacking in some areas. 🙂

    Also thanks a lot for your help on this!

    • Author
      Dan Franciscus 5 years ago

      Yep, I believe that is it. Nothing to be sorry about as I probably should have stated that in the article or the script. It may work if you just change Invoke-Command to -ComputerName localhost. I would have to do some testing though.

  10. Paul 5 years ago

    Sweet…I will change that around and test it out a little later. Thanks!

  11. John 5 years ago

    Dan,

    Found your script while looking for an automated way to upgrade to Windows 10 Pro, I am having a few issue with your scrip. Namely when the $DisableRDP function is in the script at approx line 160, and I run the script I get the following errors :

    At C:\scripts\mdt\Invoke-Windows10Upgrade.ps1:165 char:74
    + Netsh advfirewall firewall set rule group=”remote desktop” new e …
    + ~~~~~~~
    The string is missing the terminator: “.
    At C:\scripts\mdt\Invoke-Windows10Upgrade.ps1:163 char:73
    + Invoke-Command –Computername $ComputerName –ScriptBlock {
    + ~
    Missing closing ‘}’ in statement block.
    At C:\scripts\mdt\Invoke-Windows10Upgrade.ps1:162 char:9
    + {
    + ~
    Missing closing ‘}’ in statement block.
    At C:\scripts\mdt\Invoke-Windows10Upgrade.ps1:25 char:5
    + {
    + ~
    Missing closing ‘}’ in statement block.
    At C:\scripts\mdt\Invoke-Windows10Upgrade.ps1:3 char:34
    + function Invoke-Windows10Upgrade {
    + ~
    Missing closing ‘}’ in statement block.
    + CategoryInfo : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : TerminatorExpectedAtEndOfString

    If I remove the $DisableRDP function and run the script its just returns me back to the prompt, It does not prompt me to enter in credentials.

    Here is how i invoke the script from a powershell command running as administrator.
    PS C:\scripts\mdt> .\Invoke-Windows10Upgrade.ps1 -ComputerName CDF70R1 -Credentials $Credentials -AllowRDP

    I edited the functions to add the other values like the user Paul asked you about. i.e. THe $MDTLiteTouchPath etc.

    any insight ?
    lowRDP

  12. Author
    Dan Franciscus 5 years ago

    Hi Paul, lets take this to Github. I will take a look.

    https://github.com/dfranciscus/Invoke-Win10Upgrade/issues/1

  13. Author
    Dan Franciscus 5 years ago

    See https://github.com/dfranciscus/Invoke-Win10Upgrade/issues/1

    Try manually retyping -Value 1 in the $DisableRDP block. The hyphen is some other encoding or something and was messing it up.

  14. John 5 years ago

    Dan,

    Re-typing the hyphen did the trick with the error.

    I now run the script (As Administrator), with these values :
    Invoke-Windows10Upgrade -ComputerName FZX60R1 -Credential $Credential -AllowRDP -DisableRDP
    (the other values I have put in the script itself).

    I get nothing from the scrip, it goes right back to the prompt. Shouldnt the scipt prompt me for credentials to use ?

  15. Author
    Dan Franciscus 5 years ago

    Hi,

    Again I would ask to use Github for issues at this point since there may be more.

    https://github.com/dfranciscus/Invoke-Win10Upgrade/issues

     

  16. John 5 years ago

    Dan,

    I know this might be a bit off topic for this in-place upgrade of Windows 10.

    I have looked at both Windows 10 Professional and Windows 10 Enterprise, to upgrade our Windows 7 Professional computers to, Both version of Windows 10 are bloated with software that I do not think is needed in an enterprise setting for example we don’t need Bing Weather/Calendar/Camera/Candy Crush/Minecraft/Grove Music/Pandora/etc.

    Do you know of a version of Windows 10 that does not come with all this bloatware ? I have found a power shell script online that will uninstall/remove those files, but any update i.e. the Creators update they are back, and more are added.

  17. Machher 5 years ago

    Hi,

    Im unsure how to the run the invoke command? I have tried putting the whole line in both command prompt and in PS. But they both complain about Invoke-Windows10Upgrade is nto a valid command.

    Is Invoke-windows10Upgrade the name of the script?

    Im not sure how to add a screen grab…

  18. Mohammed 5 years ago

    Im having difficulty in understanding how to run the “invoke-Windows10Updgrade.  Do i copy the command in powershell or CMD? when i run it in both PS and CMD it give me an error.  I renamed the previous script to invoke-Windows10Updgrade”, thinking that the last bit would call the other script.  Nope. Still doesnt work.

    HELP!!

    • Michael Pietroforte 5 years ago

      Mohammed, you first have to execute the script at the end of the article (click Expand code) on a PowerShell console, then you can run Invoke-Win10Ugrade.

  19. Mike 4 years ago

    Hi Dan,

    I got your great script running but when it kicks off the RDP session I get the popup asking if I trust this connection, which won’t work when I try to run it at night!  Do you know how to stop that from happening?

    Thanks,

    Mike

    • Author
      Dan Franciscus 4 years ago

      Hmm. Are both machines in Active Directory? That would be one requirement, unless you are using PKI/or SSL certificates on the client.

      • Mike 4 years ago

        Brain cramp on my side, forgot uncheck Drives & Printers from the RDP client on the server.

        I have no powershell abilities at all 😉 , is there a way to add into the script the username / password to use?  Right now I manually paste them into the powershell prompt before invoking it.  I’d like to be able to schedule the whole thing to run at night.

        Thanks,

        Mike

        • Author
          Dan Franciscus 4 years ago

          There are a few ways to do this. I would recommend for security purposes, encrypting the password to a file and then decrypting when executing the script. This will help you.

          https://blog.kloud.com.au/2016/04/21/using-saved-credentials-securely-in-powershell-scripts/

          • Mike 4 years ago

            Thanks for the quick reply.  I got that setup and the script scheduled, which starts fine and the target pc reboots fine, but then nothing else happens and no logs get created in the MDT servers log folder although  Task scheduler shows the job still running.  Any ideas on how I can log what’s happening?  I tried adding start-transcript in your script but kept getting errors and when I put it in powershell script I’m scheduling I get:

            **********************
            Windows PowerShell transcript start
            Start time: 20180621110729
            Username: PCHP\sched
            RunAs User: PCHP\sched
            Machine: PCHPMSODC (Microsoft Windows NT 6.3.9600.0)
            Host Application: Powershell.exe -ExecutionPolicy Bypass c:\scripts\Scheduled1803Upgrade.ps1
            Process ID: 2368
            **********************
            Transcript started, output file is C:\scripts\task.log
            **********************
            Windows PowerShell transcript end
            End time: 20180621110841
            **********************

  20. Author
    Dan Franciscus 4 years ago

    Are you doing something like this? Does it work outside of task scheduler?

    Start-Transcript <parameters and stuff>

    Invoke-Win10Upgrade <parameters and stuff>

    Stop-Transcript <parameters and stuff>

  21. Mike 4 years ago

    Start-Transcript -Path C:\scripts\task.log -Force
    Set-location -Path c:\scripts

    $username = “schedjob@pchp”
    $password = thepassword
    $securestringpwd = $password | ConvertTo-SecureString -AsPlainText -Force
    $Credential = New-Object System.Management.Automation.PSCredential -ArgumentList $username, $secureStringPwd

    . .\Invoke-Windows10Upgrade
    Invoke-Windows10Upgrade -ComputerName testdesktop3 -Credential $Credential -MDTLiteTouchPath ‘\\MDT\Build$\Scripts\LiteTouch.vbs’ -MDTComputerName MDT.pchpmd.com -MDTRoot ‘D:\DeploymentShare’

    Stop-Transcript

    had to put in the . .\InvokeWindows10Upgrade because originally I was getting unknown function error.

  22. Rick 4 years ago

    Hi Dan.. Is there a way to modify this so the task sequence ID can be passed in to the script instead of hard-coding it in customsettings.ini?  Thanks

  23. Kurt 4 years ago

    You could start the litetouch.vbs also via psexec. Only as an idea.

    psexec \hostname1,hostname2 -i -u domainuser cmd.exe /c \MDTserverdeploymentshare$scriptsLiteTouch.vbs Bearbeiten

  24. james 3 years ago
    Hello,
    I can not execute the script because the variable Credential does not work

  25. Nathan C Masten 3 years ago

    Hi Dan,

     

    I get to the end of the script and The Task Sequence Windows appears but it is blank. Even though I specified the task sequence number and to skip the Task Sequence in the custom settings.ini do you know that is happening?

Leave a reply

Your email address will not be published.

*

© 4sysops 2006 - 2022

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account