Jump to content
Brendo

Major Windows 10 Updates (Anniversary, Creators)

Recommended Posts

Just a simple script to install Creators Update on Win 10 machines. Feel free to post any changes you think others may find useful

win10_2.png.e20c3e9075e269477318dfb6e71578fa.png

win10_1.png.cee31e42c15030768b97a6d3cad5ebc7.png

Usage:

1. Download iso using media creation tool (suggest using the dual x86/x64 option). Extract to a central location (eg. server)

2. Select script to run on machine/s

3. Enter path to the extracted iso in the parameters field when the schedule page appears (eg. \\FILE01\Install\Win10_C)

Notes:

- machine will reboot immediately after doing its prep (can be negated with /noreboot parameter)

- it can take a while before the prep completes, you'll notice 4 setup*.exe files which should change their ram usage every now and then which indicates it's still running

- current settings are for Creators Update

- '/compat ignorewarning' argument used to bypass issues such as different install language

- will also work with Anniversary Update and future updates. Just make sure to update the value on line 1 to appropriate build number

- ensure appropriate permissions to network share for robocopy to do it's thing

- not sure best approach when it comes to uac, but using Process Execute as Admin (Line 4) seems to do the trick

- using 'as Admin' means that setup.exe is run using the credentials defined in client/location. Could also use 'as User' and define credentials

-15063 (creator update) 16299 (fall creator update)

 

Links:

Media: https://www.microsoft.com/en-au/software-download/windows10

Arguments: https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/windows-setup-command-line-options

 

Download:

Post #6

NOTE: More advanced script by tlphipps HERE

 

Edited by Brendo

Share this post


Link to post
Share on other sites

Hi!

 

I've been trying to create pretty much the same script, however what's driving me nuts is I can get the entire script to work until it need to execute the setup. I can only get it to run on "Console execute" however I then get stuck because of UAC. Am I missing something here? The files copy ok and if you run setup manually it works fine.

Share this post


Link to post
Share on other sites

IF UAC is the only issue, then I would enable automatic login, disable UAC, reboot and run the setup, clear the automatic login and queue a script to re-enable UAC after the next restart.... If you are doing this, "intrusive" or "disruptive" is no longer a concern. You (should) have full reign over the computer for an hour or two if you are trying to script this, what are another couple of restarts?

Share this post


Link to post
Share on other sites

Hey, Any chance we could get you you to just post up the actual script so we can download and edit as needed? I know I'm lazy. Really appreciate you posting though.

Thanks

Share this post


Link to post
Share on other sites
Hey, Any chance we could get you you to just post up the actual script so we can download and edit as needed? I know I'm lazy. Really appreciate you posting though.

Thanks

Here you go

 

I'm lazy too, so you'll see the attached scripts may have some stuff edited out compared to the pictures

 

Scripts -> Maintenance -> Patching

Win10 Major Update.zip

Edited by Guest

Share this post


Link to post
Share on other sites
Can anyone say they have this working in production?

 

I was going to ask the same question. I tried this script, and it fails every time identifying the network path, saying it cannot find the setup.exe and it terminates. I also find that the registry key it queries for Windows version doesn't exist on systems I have tested with. It appears to have not been tested. I'll be publishing my own once I've done a rewrite and debug, with my own version query routines.

Share this post


Link to post
Share on other sites

Going only from the picture, Step 6 runs as SYSTEM. That means that the share for the files must be accessible by "DOMAINNAME\Domain Computers". By default a share will be available to "BUILTIN\Users", which includes "DOMAINNAME\Domain Users", which does NOT include computer accounts. This won't work in a workgroup, unless you have a user account to work with and change to "Shell As User". Also, the ISO needs to be extracted, so the path should not have an .iso file, but instead have all the files from the .iso, such as setup.exe.

 

FWIW, testing on my system, the reg key looks fine:

C:\>reg query "HKEY_LOCAL_MACHINE\software\microsoft\windows nt\currentversion" /v "CurrentBuild"

HKEY_LOCAL_MACHINE\software\microsoft\windows nt\currentversion
   CurrentBuild    REG_SZ    15063

Just throwing out things that might help...

Share this post


Link to post
Share on other sites

Hi Darren,

 

I already re-wrote the version query to just issue a PowerShell command and an evaluation of %powershellresult% because I tested several systems and they didn't have the registry keys mentioned.

 

As for the Windows files portion, I actually decided to rewrite , trying one of the following:

-A PowerShell command that extracts the ISO to the local directory instead of pre-extracted and Robocopy (easier to put the ISO on file shares)

-A PowerShell command that mounts the ISO from the share as a drive on the agent

 

I'll have to test on multiple machines at once to see the I/O impact of both, but the IF EXIST with the @pathname@ variables has been the issue so far. Sounds like I can't use an IF EXIST filename unless a system is either domain-joined or the path is local? I've been testing on a workgroup machine. I really want this to work whether the pathname is on a domain server, workgroup server, or a NAS box that gives everyone read-only access to a given share.

Share this post


Link to post
Share on other sites

Yes, the original script has some issues with getting from the network at times

 

It all works...but not in every setup (it is simplified after all). My original hope for posting was as a starting point for others to build off

 

I do wonder about running the setup.exe through psexec in order to get around uac and where the instances start, but don't actually seem to be doing anything, I've just not used that before

Share this post


Link to post
Share on other sites
Yes, the original script has some issues with getting from the network at times

 

It all works...but not in every setup (it is simplified after all). My original hope for posting was as a starting point for others to build off

 

I do wonder about running the setup.exe through psexec in order to get around uac and where the instances start, but don't actually seem to be doing anything, I've just not used that before

 

Probably unlikely. The issue with drive mounting is that the drive (or share) has to exist in whatever context the user running the setup is. This is especially problematic for workgroup systems, because the shell commands are run as the SYSTEM account (IIRC) and so when a drive is mounted, it isn't mounted as the current logged on user. Secondly, for workgroup systems, this means a user actually has to be logged on for the setup to run.

 

I'm still playing with the script, I've been sidetracked by a bunch of different things. I'll post some of my efforts when I have a moment. One suggestion --I would clarify when you post a script about whether you're using it in production, if it's in testing, or you have encountered any issues. It helps people who are building off of your work anticipate potential things they might need to work through.

Share this post


Link to post
Share on other sites

I've been doing testing on this as well. A lot of the issues I was having with the upgrade was due to the media being used. Yes, the media creation tool generates an ISO, but it won't work with an Enterprise install, for example. I'm not ready to post my script yet, but basically it works out like this:

 

Get the OS version:

select ComputerOSFullVersion FROM v_xr_computers where ComputerID = %computerid%

If 10.0.15063 go to SendEmailReport,

 

get edition variable

select ComputerOS from v_xr_computers where ComputerID = %computerid%

If Enterprise go to :ISOCopy-Ent

If Pro go to :ISOCopy-Pro

Log: Window10Home upgrades not covered under contract. Exiting.

 

:ISOCopy

Verify ISO copied

Call Iso copy script

:Install

cmd

Sleep 15 minutes, then loop 4 times

Send failure report after 4th loop.

:EmailScriptReport

Share this post


Link to post
Share on other sites

I'm running into an issue mounting shares as a workgroup user.

I've set the script to use a ConsoleShell command with console as %consoleid% that looks like this:

 

net use @DriveLetter@ @Path to ISO@ /user:@Domain\Username@ @Password@ /persistent:no

 

This command works perfectly from a non-administrative command prompt as the logged in user (substituting for the variables. It does *not* work in the script. I'm unsure why. If I could get this to work, I then have a powershell script that can mount the ISO from that share.

Share this post


Link to post
Share on other sites
I'm running into an issue mounting shares as a workgroup user.

I've set the script to use a ConsoleShell command with console as %consoleid% that looks like this:

net use @DriveLetter@ @Path to ISO@ /user:@Domain\Username@ @Password@ /persistent:no

Have you tried the "Console Execute" function instead of the "Console Shell" one? Execute returns no results, but truly runs as the user. The Shell one doesn't have access to all of the user's resources (somehow). I don't know what they actually do differently, only that there is a difference.

Share this post


Link to post
Share on other sites
I'm running into an issue mounting shares as a workgroup user.

I've set the script to use a ConsoleShell command with console as %consoleid% that looks like this:

net use @DriveLetter@ @Path to ISO@ /user:@Domain\Username@ @Password@ /persistent:no

Have you tried the "Console Execute" function instead of the "Console Shell" one? Execute returns no results, but truly runs as the user. The Shell one doesn't have access to all of the user's resources (somehow). I don't know what they actually do differently, only that there is a difference.

 

Thank you for the suggestion. It still doesn't work. Wondering if I should be specifying a console number instead of just %consoleid%.

 

LabTech's examples showed having an "If user is logged on" option in their scripts, but I'm not using it; right now I just wanted to go with "Assume a user is logged on, do what I want" and then gussy things up later. There's got to be something I'm not seeing.

Share this post


Link to post
Share on other sites

It's my understanding that if the "If user is logged on" option isn't turned on, the %consoleid% variable is never created.

 

In fact, I just checked my list of dumped variables and the %consoleid% variable isn't in it. You definitely need to have that turned on.

Share this post


Link to post
Share on other sites

Teckmonkey, I changed my script to a consoleid of 0 on a hunch, and it's working. So that hurdle is over --for now. I may have to go back and do that later, in the event a system has multiple console ids, but for now I'll keep it.

 

My next piece of the script is (possibly soon-to-be "was") a powershell script that mounts the ISO. This too works on its own, but does not in the regular "Execute Script" task of LabTech scripting, once again likely because it's not running in the local user context. I think I'd have to change that to a "Console "Execute" step to work, which would complicate things such as the output logging I need for steps after that, and it would require that I use a .ps1 file instead of just pasting the script in. That may not be a good option, so I may have to require the ISO be extracted in the share I'm pointing to. Annoying, but possibly necessary.

 

This might mean I also make a feature request to LabTech to add "Logged In User" as a "Script Credentials" option in the Execute Script function, as it would be incredibly helpful.

Share this post


Link to post
Share on other sites

Okay. Update: I've managed to get the script to first map a network share with a stored ISO, then execute a Powershell script to mount the ISO.

 

Current issues before going forward:

 

1) This testing was done with the PowerShell script hard-coded to know which drive letter I had specified to map, and the name of the .ISO file. What I'd really want to do is have those variables passed to the script, but as I can't use the standard script call in LabTech (I had to use a Console Execute command), I can't pass variables to this script.

2) Because of issue #1, I also can't get the output of the script either, and immediately use that to call the setup files from the drive letter. I can work around this by having the script write its output to a text file, read that file to know what drive letter the ISO is mounted as, and start setup, but that's a little more clunky.

 

If I can get the above two things to work without kludging them, I've done the hard work of the script and everything else will flow smoothly. I'll need to provide everyone with both the LabTech script and the Powershell script once I'm done. Ah, the joys of requiring that I run things in the logged-in user's context....

Share this post


Link to post
Share on other sites

You should add the "IF User Logged On" step so that you have the %consoleid% variable. It is possible for it not to be 0.

Can you solve some of the other issues by pushing more into the PowerShell? Like, have it run the NET USE command to establish access, and have it perform the mount, determine the drive letter, run the setup, etc.? That way you aren't involving the Labtech Script each time. If you are trying to perform a step, wait for completion and then continue, it's not automatic when you are not running the command directly. There are also ways to have Labtech "sniff" the status of the script running on the agent and figure out when it has finished, and then continue.

 

One way to get around credentials being written to files or visible as parameters to a long running process is to use a small loader script that performs the mapping, fires off a second script to continue running the in the background, and then exits. You can have the loader script spawn it's own delete command as it exits, or make the second script wait 2 seconds and then delete the first one.

Share this post


Link to post
Share on other sites

I've got the PowerShell script hammered out now.

The LabTech script queries the existing version of the system it is executed on. If it is currently on the Creator's edition, it exits.

The LabTech script executes a Console Shell command to map the drive using Parameters supplied at the start of the script.

The LabTech script writes the variables of the mapped drive letter and of the iso name to text files.

The LabTech script does a Console Execute command to execute the PowerShell script.

The PowerShell script reads the text files into variables and mounts the ISO.

The Powershell script does its work, then echos the ISO drive letter back out into a text file.

LabTech reads the text file into a variable to get ready to start the Windows setup. This way, you don't have to worry about what drive letter is free, the PS script will pick it and give it to you.

 

I've now got to actually test the Windows Upgrade, which will probably happen early next week. But this was the hard stuff.

 

I'll provide everyone with the tools once I've got it all set. I'll need to add the "If Logged In" stuff, but that's easy compared to what I needed for everything else.

Share this post


Link to post
Share on other sites

I THINK I have solved this challenge but with a slight twist from what you guys are doing. I've opted to store the ISO file for our latest 'approved' Win10 build on our CWA server and then have the client systems download directly from us (but leverage CWA caching function to store it inside the network when first agent downloads it). I did this because we support far more laptops than desktops so our users are often not local to a file share and I didn't want to distribute the ISO to multiple file servers.

 

My attached script does the following:

- Checks if machine is 'eligible to upgrade' (is it running a version older than what we're installing)

- Downloads ISO file from our CWA server (or uses CWA cache folder if it's already been downloaded)

- If no user logged in, proceeds with upgrade. If user logged in, asks them if we can proceed. If they say no, automatically reschedules to run again in 10 hours (arbitrary number I picked)

- Mounts ISO with powershell and then uses robocopy to extract the ISO contents to temp folder. Then unmounts and deletes ISO.

- kicks machine back to login screen then proceeds with upgrade (I found upgrade more reliable this way....keeps the users from starting something else while it's running)

- script then pauses for 2 hours and then performs a 'version check' to see if the upgrade completed

- notifies tech running the script of failure/success via email (thanks to Darren's awesome function script)

 

I've done several successful tests with this and have even successfully added this to the CWA tray icon to allow users to 'self run' the upgrade. We're getting ready to launch/communicate this to a much broader audience. So if you guys find any issues with this, PLEASE let me know! Hopefuly this helps somebody.

 

NOTE: Make sure you download the ISO file to your CWA server and adjust line 17 to point to the correct ISO. We've had the most luck using the ISO from the MS VLSC rather than the 'consumer' ISO.

 

See updated post with latest version here: https://www.labtechgeek.com/topic/3535-major-windows-10-updates-anniversary-creators/?do=findComment&comment=23001

 

Edited by tlphipps

Share this post


Link to post
Share on other sites

Wow. Looks great guys. We have been up to this point downloading it from the CWA server also because (like you tlphipps) have majority laptops globally. Wasn't sure if that was the best way but appears so! Definitely going to have to adapt our scripts to include some of the ideas here!

 

Any chance CW is working on actually making it work through PM? We did several tests actually today and it seems to download and try to process (even prompting for reboot), but upon reboot, nothing.

Share this post


Link to post
Share on other sites
My attached script does the following:

....

- If no user logged in, proceeds with upgrade. If user logged in, asks them if we can proceed. If they say no, automatically reschedules to run again in 10 hours (arbitrary number I picked)

- kicks machine back to login screen then proceeds with upgrade (I found upgrade more reliable this way....keeps the users from starting something else while it's running)

I thought that the upgrade required operating as a logged in user. (I haven't ever tried it). It sounds like you are running with nobody logged in, and if they are logged in you log them out before proceeding. So it can be pushed silently, with no consent from a console user?

 

- script then pauses for 2 hours and then performs a 'version check' to see if the upgrade completed
For a script that is not marked as an offline script, I am pretty sure that even if you pause, if the agent does not check in within a 15 minute window the script engine will kill the running script. Assuming I am correct, there are two ways to get around it.

Start by setting a variable with a timestamp for the current date/time. Also get the current uptime. You may/will need these later.

Some good queries:

SET:  @UPGRADESTARTED@ = SQLRESULT[sELECT round(NOW()+0,0);]
SET:  @COMPUTERSTARTUP@ = SQLRESULT[sELECT round(DATE_SUB(lastcontact,INTERVAL uptime MINUTE)+1,0) FROM computers WHERE computerid='@computerid@';]

  1. For the "Online Script" approach:
    • Once you kick off the upgrade, set a variable or script state variable such as "UPGRADEINPROCESS=YES".
    • Next, schedule to run the current script in 15 minutes time (as frequently as you want to check in on it).
    • Exit the current script.
    • Modify the script so that each time it starts, you check for the "UPGRADEINPROCESS" variable. If it is set, skip all the beginning checks. Just do these tests:
    1. See if a restart has occurred with: IF
        >  @COMPUTERUPTIME@  THEN  Jump to :ComputerHasRebooted
    2. See if this is taking too long, so you are considering it failed with: IF [sql SELECT NOW() > DATE_ADD(TIMESTAMP('@UPGRADESTARTED@'),INTERVAL 6 HOUR)+0,0);] > 0 THEN Jump to :UpgradeHasTimedOut

    [*]If you get past both tests, then the machine has not rebooted and you are still within a 6 hour window, so again re-queue the script for 15 minutes time and exit.

    [*]This loop will repeat until the agent has restarted (and then you can perform version checks, etc.) or too much time has elapsed, and then you can email the technician and tell them that the upgrade was not completed within 6 hours and is believed to have failed.

    [*]Because it requires the agent to be online, the script will queue and wait, even if the machine went offline for a few hours. Only when it come back would the script make a determination if the upgrade was successful or not. The downside to this is that you aren't guaranteed a firm cutoff time for notifications, but you don't have to specifically handle waiting, you just queue the script and whenever the agent is offline after that time the script will start.

    [*]For an Offline Script, you will need a check at the start to make sure the agent is online, before any remote agent commands are called (or the script will hang).

  • If it is not online, reschedule to run later.
  • Once you start the upgrade, instead of worrying about exiting, you can just sleep for shorter periods (5-15 minutes) and then perform the same tests the Online Script would do:
    1. See if a restart has occurred with: IF [sql SELECT round(DATE_SUB(lastcontact,INTERVAL uptime MINUTE)+0,0) FROM computers WHERE computerid='@computerid@';] > @COMPUTERUPTIME@ THEN Jump to :ComputerHasRebooted
    2. See if this is taking too long, so you are considering it failed with: IF [sql SELECT NOW() > DATE_ADD(TIMESTAMP('@UPGRADESTARTED@'),INTERVAL 6 HOUR)+0,0);] > 0 THEN Jump to :UpgradeHasTimedOut

    [*]If you get past both tests, then the machine has not rebooted and you are still within a 6 hour window you just sleep and then jump back up to the variable checks.

    [*]This loop will repeat until the agent has restarted (and then you can perform version checks, etc.) or too much time has elapsed, and then you can email the technician and tell them that the upgrade was not completed within 6 hours and is believed to have failed.

    [*]The advantage of this is that the script will never be terminated just because the agent was offline for a period, you don't have to deal with the script exiting and being restarted, and you will get notification right after your cutoff window that the upgrade failed.

    [*]The disadvantage is that you have extra complexity making sure the agent is online. With a standard Online script, you are assured that the script will never even start running unless the agent is active.

 

- notifies tech running the script of failure/success via email (thanks to Darren's awesome function script)
ThankYouForUsingMyScripts. :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×