Created
October 24, 2018 20:15
-
-
Save marsell/dac4771a6a313e404258112c09687db3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{"set_internal_metadata":{"operator-script":"# This Source Code Form is subject to the terms of the Mozilla Public\n# License, v. 2.0. If a copy of the MPL was not distributed with this\n# file, You can obtain one at http://mozilla.org/MPL/2.0/.\n#\n# Copyright (c) 2018, Joyent, Inc.\n#\n# Set Window's cleanmgr to (nearly) max, and run it. This cleans up most\n# temporary (files, cache) and unneeded data (outdated installation data).\n#\n# In order for this script to work, a Windows image needs to have mdata-get.exe,\n# mdata-put.exe and prepare_image_runner.ps1 installed in C:\\smartdc\\bin, and\n# prepare_image_runner.ps1 should be run by Windows on every boot. Upon boot,\n# prepare_image_runner.ps1 will then check if \"sdc:operator-script\" metadata\n# (seen as internal_metadata.\"operator-script\" in \"vmadm get\" output) is present\n# over COM2, and run it. If it's not present, booting continues as normal.\n#\n# Apparently, the only way to get cleanmgr to run without displaying a final\n# information dialog -- thus hanging image creation -- is through the /autoclean\n# flag. We abuse this by setting all available cleanup options in the registry\n# to be run by autoclean. Since the VM will be rolled back after image creation,\n# this change is not a problem.\n#\n# There are also a couple very expensive cleanmgr checks that increase\n# cleanmgr's run time up to 5x, which we cannot afford with the 5m time limit\n# imposed on image creation between prepare-script 'running' and\n# final 'error'/'success' calls. The only way to disable these checks outright\n# is to temporarily move their registry keys, which we do as well.\n#\n# After that, cleanmgr is run, then moving the expensive registry keys back.\n#\n# Unfortunately, cleanmgr /autoclean appears to contain its own logic about when\n# it will clean up something. As a result, we also empty recycle bins and clear\n# most temp and log directories manually.\n\n$parent_path = 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\VolumeCaches'\n$tmp_parent_path = 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer'\n$expensive_cleanups = 'Update Cleanup', 'System error memory dump files'\n$clean_dirs = 'c:\\Windows\\Temp\\*', 'c:\\Windows\\Logs\\*', 'c:\\Windows\\Minidump\\*',\n 'C:\\PerfLogs\\*', 'C:\\Windows\\Downloaded Program Files\\*',\n 'C:\\Windows\\*.log', 'C:\\Users\\*\\AppData\\Local\\Temp\\*'\n\n\nfunction mput($key, $val) {\n c:\\smartdc\\bin\\mdata-put.exe prepare-image:$key $val\n}\n\nfunction setting_path($id) {\n \"$parent_path\\$id\"\n}\n\nfunction tmp_path($id) {\n \"$tmp_parent_path\\$id\"\n}\n\nfunction error($msg) {\n echo \"ERROR\"\n echo $msg\n mput 'state' 'error'\n mput 'error' $msg\n exit\n}\n\n\necho 'Starting run...'\nmput 'state' 'running'\n\necho \"Disabling particularly expensive cleanmgr operations\"\nforeach ($cleanup in $expensive_cleanups) {\n try {\n Move-Item -LiteralPath (setting_path $cleanup) `\n -Destination (tmp_path $cleanup) -ErrorAction Stop\n } catch [System.Management.Automation.PSInvalidOperationException] {}\n}\n\necho 'Marking all other checks for /autoclean'\ntry {\n $cleanups = (Get-Item -LiteralPath $parent_path).GetSubKeyNames()\n} catch {\n error 'Unknown hive'\n}\n\n$add_auto_paths = @()\ntry {\n foreach ($cleanup in $cleanups) {\n $path = setting_path $cleanup\n $node = Get-Item -LiteralPath $path\n if ($node.GetValue('Autorun') -ne 1) {\n $add_auto_paths = $add_auto_paths + $path\n }\n }\n} catch {\n error 'Bad Get-Item'\n}\n\ntry {\n foreach ($path in $add_auto_paths) {\n Set-ItemProperty -LiteralPath $path -Name 'Autorun' `\n -Type Dword -Value 1 -ErrorAction Stop\n }\n} catch {\n error 'Bad Set-Item'\n}\n\necho 'Running cleanmgr...'\ntry {\n # Out-Null needed to block script until cleanmgr completes\n c:\\windows\\system32\\cleanmgr.exe /autoclean | Out-Null\n} catch [System.Management.Automation.CommandNotFoundException] {\n # Ignore, in case we are dealing with a 2012r2 instance without\n # Desktop Experience installed\n} catch {\n error 'Bad cleanmgr'\n}\n\necho 'Unmarking other checks /autoclean'\ntry {\n foreach ($path in $add_auto_paths) {\n Set-ItemProperty -LiteralPath $path -Name 'Autorun' `\n -Type Dword -Value 0 -ErrorAction Stop\n }\n} catch {\n error 'Bad auto undo'\n}\n\necho 'Reenabling expensive cleanmgr operations'\nforeach ($cleanup in $expensive_cleanups) {\n try {\n Move-Item -LiteralPath (tmp_path $cleanup) `\n -Destination (setting_path $cleanup) -ErrorAction Stop\n } catch [System.Management.Automation.PSInvalidOperationException] {}\n}\n\necho 'Empty Recycle Bins'\ntry {\n Clear-RecycleBin -Confirm:$false -ErrorAction Stop\n} catch [System.ComponentModel.Win32Exception],\n [System.Management.Automation.CommandNotFoundException] {\n # Ignore, in case we are dealing with a Powershell older than 5.1 on 2012r2.\n # By default, 2012r2 has Powershell 4.0, but updates can increase it to 5.1\n} catch {\n error 'Bad empty recycle'\n}\n\necho 'Clear out temp and log directories'\nforeach ($path in $clean_dirs) {\n try {\n Remove-Item -Path $path -Recurse -Force -ErrorAction Stop\n } catch {}\n}\n\n\nmput 'state' 'success'\necho 'Done!'\n"}} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment