summaryrefslogtreecommitdiff
path: root/packer/files/scripts
diff options
context:
space:
mode:
authorheqnx <root@heqnx.com>2025-07-11 21:50:55 +0300
committerheqnx <root@heqnx.com>2025-07-11 21:50:55 +0300
commit8cf16b5c899a60ea5982c5d8dc042153daf6ac5b (patch)
treed64092854fe32f4630f514b93b244b0b5eddc5d1 /packer/files/scripts
parent54ecdd04947e70026c96365ea29463f8b435c1aa (diff)
downloadansible-active-directory-range-8cf16b5c899a60ea5982c5d8dc042153daf6ac5b.tar.gz
ansible-active-directory-range-8cf16b5c899a60ea5982c5d8dc042153daf6ac5b.zip
added packer templates
Diffstat (limited to 'packer/files/scripts')
-rwxr-xr-xpacker/files/scripts/create-checksums.sh41
-rw-r--r--packer/files/scripts/linux/init.sh4
-rw-r--r--packer/files/scripts/linux/setup-qemu-guest-agent.sh11
-rw-r--r--packer/files/scripts/linux/sysprep.sh271
-rw-r--r--packer/files/scripts/windows/cleanup.ps1132
-rw-r--r--packer/files/scripts/windows/disable-updates.ps113
-rw-r--r--packer/files/scripts/windows/enable-winrm-http.ps129
-rw-r--r--packer/files/scripts/windows/init.ps125
-rw-r--r--packer/files/scripts/windows/setup-qemu-guest-agent.ps114
-rw-r--r--packer/files/scripts/windows/sysprep-shutdown.bat6
10 files changed, 546 insertions, 0 deletions
diff --git a/packer/files/scripts/create-checksums.sh b/packer/files/scripts/create-checksums.sh
new file mode 100755
index 0000000..a8143cb
--- /dev/null
+++ b/packer/files/scripts/create-checksums.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+set -e
+
+PACKER_BUILD_NAME="${PACKER_BUILD_NAME}"
+NAME="${NAME}"
+TIMESTAMP="${TIMESTAMP}"
+
+if ! command -v md5sum &>/dev/null; then
+ printf "%s\n" "[WARN] md5sum not found, skipping"
+ exit 0
+fi
+
+if ! command -v sha512sum &>/dev/null; then
+ printf "%s\n" "[WARN] sha512sum not found, skipping"
+ exit 0
+fi
+
+if test -z "${PACKER_BUILD_NAME}" || test -z "${NAME}" || test -z "${TIMESTAMP}"; then
+ printf "%s\n" "[WARN] \$PACKER_BUILD_NAME|\$NAME|\$TIMESTAMP not supplied for checksum creation, skipping"
+ exit 0
+fi
+
+OUTPUT_DIR="output/${PACKER_BUILD_NAME}"
+mkdir -p "${OUTPUT_DIR}" &>/dev/null
+
+if test "${PACKER_BUILD_NAME}" == "qemu"; then
+ FILENAME="${PACKER_BUILD_NAME}-${NAME}_${TIMESTAMP}.qcow2"
+ mv "${PACKER_BUILD_NAME}_output_${NAME}/${PACKER_BUILD_NAME}-${NAME}_${TIMESTAMP}" "${OUTPUT_DIR}/${FILENAME}"
+else
+ FILENAME="${PACKER_BUILD_NAME}-${NAME}_${TIMESTAMP}.ova"
+ mv "${PACKER_BUILD_NAME}_output_${NAME}/${PACKER_BUILD_NAME}-${NAME}_${TIMESTAMP}.ova" "${OUTPUT_DIR}/${FILENAME}"
+fi
+rm -rf "${PACKER_BUILD_NAME}_output_${NAME}"
+
+(
+ cd "${OUTPUT_DIR}"
+ md5sum "${FILENAME}" > "${FILENAME}.sums"
+ sha512sum "${FILENAME}" >> "${FILENAME}.sums"
+)
+
+printf "%s\n" "[INFO] created md5 and sha512 checksums for ${OUTPUT_DIR}/${FILENAME}"
diff --git a/packer/files/scripts/linux/init.sh b/packer/files/scripts/linux/init.sh
new file mode 100644
index 0000000..04b7257
--- /dev/null
+++ b/packer/files/scripts/linux/init.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+set -e
+pushd "$(dirname ${BASH_SOURCE:0})" &>/dev/null
+trap 'popd &>/dev/null' EXIT
diff --git a/packer/files/scripts/linux/setup-qemu-guest-agent.sh b/packer/files/scripts/linux/setup-qemu-guest-agent.sh
new file mode 100644
index 0000000..8a242ef
--- /dev/null
+++ b/packer/files/scripts/linux/setup-qemu-guest-agent.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+set -e
+pushd "$(dirname ${BASH_SOURCE:0})" &>/dev/null
+trap 'popd &>/dev/null' EXIT
+
+export DEBIAN_FRONTEND=noninteractive
+
+apt-get update
+apt-get install -y qemu-guest-agent
+apt-get clean
+apt-get autoclean
diff --git a/packer/files/scripts/linux/sysprep.sh b/packer/files/scripts/linux/sysprep.sh
new file mode 100644
index 0000000..d232a6f
--- /dev/null
+++ b/packer/files/scripts/linux/sysprep.sh
@@ -0,0 +1,271 @@
+#!/bin/bash
+# taken from https://github.com/DanHam/packer-virt-sysprep
+set -o errexit
+shopt -s nullglob dotglob
+
+function _clean_shell_history() {
+ root_hist="$(find /root -type f -name .bash_history)"
+ user_hist="$(find /home -type f -name .bash_history | tr -s '\n' ' ')"
+ rm -rf ${root_hist} ${user_hist}
+
+ set +o errexit
+ if [[ -f /.dockerenv ]]; then
+ ln -sf /dev/null "/root/.bash_history"
+
+ while read user home; do
+ ln -sf /dev/null "${home}/.bash_history" || :
+ chown --no-dereference "${user}:${user}" "${home}/.bash_history" || :
+ done <<< $(getent passwd | grep -i home | awk -F ':' '($3>=1000) {print $1" "$6}')
+
+ fi
+ set -o errexit
+}
+
+function _clean_home_dirs() {
+ root_files="$(find /root -name .cache -o -name .zshrc -o -name .wget-hsts | tr -s '\n' ' ')"
+ user_files="$(find /home -name .cache -o -name go -o -name .zshrc -o -name .wget-hsts | tr -s '\n' ' ')"
+ rm -rf ${root_files} ${user_files}
+}
+
+function _clean_cloud_init() {
+ rm -rf /var/log/installer
+ rm -rf /var/lib/cloud/*
+ rm -rf /var/log/cloud-init.log
+}
+
+function _clean_logs() {
+ find /var/log -maxdepth 1 -type f -exec bash -c "echo > {}" \;
+}
+
+function _clean_crash_data() {
+ crash_data_location=(
+ "/var/crash/*"
+ "/var/log/dump/*"
+ )
+ for crash_data in ${crash_data_location[@]}; do rm -rf ${crash_data}; done
+}
+
+function _reset_dhcp_state() {
+ lease_data_locations=(
+ "/var/lib/dhclient/*"
+ "/var/lib/dhcp/*"
+ )
+ for lease_file in ${lease_data_locations[@]}; do rm -rf ${lease_file}; done
+}
+
+function _reset_fw_rules() {
+ if command -v ufw &>/dev/null; then
+ ufw --force reset &>/dev/null
+ fi
+
+ if command -v systemctl &>/dev/null; then
+ if systemctl is-active -q firewalld.service &>/dev/null; then
+ systemctl stop -q firewalld.service
+ fi
+
+ if systemctl is-active ufw.service &>/dev/null; then
+ systemctl stop -q ufw.service
+ fi
+ fi
+
+ fw_config_locations=(
+ "/etc/sysconfig/iptables"
+ "/etc/firewalld/services/*"
+ "/etc/firewalld/zones/*"
+ "/etc/ufw/user.rules.*"
+ "/etc/ufw/before.rules.*"
+ "/etc/ufw/after.rules.*"
+ "/etc/ufw/user6.rules.*"
+ "/etc/ufw/before6.rules.*"
+ "/etc/ufw/after6.rules.*"
+ )
+
+ for fw_config in ${fw_config_locations[@]}; do rm -rf ${fw_config}; done
+}
+
+function _reset_machine_id() {
+ sysd_id="/etc/machine-id"
+ dbus_id="/var/lib/dbus/machine-id"
+
+ if [[ -e ${sysd_id} ]]; then
+ rm -rf ${sysd_id} && touch ${sysd_id}
+ fi
+
+ if [[ -e ${dbus_id} && ! -h ${dbus_id} ]]; then
+ rm -rf ${dbus_id}
+ fi
+}
+
+function _clean_mail_spool() {
+ mta_list=(
+ "exim"
+ "postfix"
+ "sendmail"
+ )
+
+ mail_spool_locations=(
+ "/var/spool/mail/*"
+ "/var/mail/*"
+ )
+
+ for mta in ${mta_list[@]}; do
+ if command -v systemctl &>/dev/null ; then
+ mta_service="$(systemctl list-units --type service | grep ${mta} | cut -d' ' -f1)"
+ if [[ "x${mta_service}" != "x" ]]; then
+ if systemctl is-active ${mta_service} &>/dev/null; then
+ systemctl stop ${mta_service}
+ fi
+ fi
+ else
+ mta_service="$(find /etc/init.d/ -iname "*${mta}*")"
+ if [[ "x${mta_service}" != "x" ]]; then
+ if ${mta_service} status | grep running &>/dev/null; then
+ ${mta_service} stop
+ fi
+ fi
+ fi
+ done
+
+ for mail_spool in ${mail_spool_locations[@]}; do rm -rf ${mail_spool}; done
+}
+
+function _clean_package_manager_cache() {
+ cache_locations=(
+ "/var/cache/apt/"
+ "/var/cache/dnf/"
+ "/var/cache/yum/"
+ "/var/cache/zypp*"
+ )
+
+ for cache_dir in ${cache_locations[@]}; do
+ if [[ -d ${cache_dir} ]]; then
+ find ${cache_dir} -type f | xargs -I FILE rm -rf FILE
+ fi
+ done
+}
+
+function _clean_package_manager_db() {
+ rm -rf /var/lib/rpm/__db.*
+ apt_lists=/var/lib/apt/lists
+ if [[ -d "${apt_lists}" ]]; then
+ find "${apt_lists}" -type f | xargs rm -rf
+ fi
+}
+
+function _clean_tmp() {
+ tmp_locations=(
+ "/tmp"
+ "/var/tmp"
+ )
+
+ mntpnt_orig_tmp="/mnt/orig_tmp"
+
+ shopt -s dotglob
+
+ sum_tmp_space=0
+ for tmp in ${tmp_locations[@]}
+ do
+ if [[ -d ${tmp} ]]; then
+ tmp_space="$(du -sm ${tmp} | cut -f1)"
+ else
+ tmp_space=0
+ fi
+ sum_tmp_space=$(( ${sum_tmp_space} + ${tmp_space} ))
+ if [[ ${sum_tmp_space} -gt 128 ]]; then
+ echo "ERROR: Space for copying tmp into memory > 128mb. Exiting"
+ exit 1
+ fi
+ done
+
+ if ! mount -l -t tmpfs | grep /dev/shm &>/dev/null; then
+ [[ -d /dev/shm ]] || mkdir /dev/shm && chmod 1777 /dev/shm
+ mount -t tmpfs -o defaults,size=128m tmpfs /dev/shm
+ fi
+
+
+ for tmp in ${tmp_locations[@]}; do
+ tmp_path="${tmp}"
+ on_tmpfs=false
+
+ while [[ ${tmp_path:0:1} = "/" ]] && [[ ${#tmp_path} > 1 ]] && [[ ${on_tmpfs} = false ]]; do
+ defifs=${IFS}
+ IFS=$'\n'
+ for mountpoint in $(mount -l -t tmpfs | cut -d' ' -f3)
+ do
+ if [[ "${mountpoint}" == "${tmp_path}" ]]; then
+ on_tmpfs=true
+ continue
+ fi
+ done
+ IFS=${defifs}
+ tmp_path=${tmp_path%/*}
+ done
+
+ if [[ "${on_tmpfs}" = false ]]; then
+ tmp_located_on=""
+ defifs=${IFS} && IFS=$'\n'
+ for line in $(df | tr -s ' ')
+ do
+ if echo ${line} | cut -d' ' -f6 | grep ^${tmp}$ &>/dev/null; then
+ tmp_located_on="$(echo ${line} | cut -d' ' -f1)"
+ fi
+ done
+ IFS=${defifs}
+ [[ "x${tmp_located_on}" = "x" ]] && tmp_located_on="/"
+
+ shmtmp="/dev/shm/${tmp}"
+ mkdir -p ${shmtmp}
+ chmod 1777 ${shmtmp}
+ files=(${tmp}/*)
+ [[ -e ${files} ]] && cp -pr ${tmp}/* ${shmtmp}
+ mount --bind ${shmtmp} ${tmp}
+
+ mkdir ${mntpnt_orig_tmp}
+ if [[ ${tmp_located_on} = "/" ]]; then
+ mount_opts="--bind"
+ tmp_path="${mntpnt_orig_tmp}/${tmp}"
+ else
+ mount_opts=""
+ tmp_path="${mntpnt_orig_tmp}"
+ fi
+ mount ${mount_opts} ${tmp_located_on} ${mntpnt_orig_tmp}
+
+ files=(${tmp_path}/*)
+ [[ -e ${files} ]] && rm -rf ${tmp_path}/*
+ umount ${mntpnt_orig_tmp} && rm -rf ${mntpnt_orig_tmp}
+ fi
+ done
+}
+
+function _clean_yum_uuid() {
+ uuid="/var/lib/yum/uuid"
+ [[ -e ${uuid} ]] && rm -rf ${uuid} || :
+}
+
+function _clean_logins() {
+ login_logs=(
+ "/var/log/lastlog"
+ "/var/log/wmtp"
+ "/var/log/btmp"
+ "/var/run/utmp"
+ "/var/run/utmp"
+ )
+ for login_log in ${login_logs[@]}; do ln -sfn /dev/null $login_log; done
+}
+
+_clean_shell_history
+_clean_home_dirs
+_clean_cloud_init
+_clean_logs
+_clean_crash_data
+_reset_dhcp_state
+_reset_fw_rules
+_reset_machine_id
+_clean_mail_spool
+_clean_package_manager_cache
+_clean_package_manager_db
+_clean_tmp
+_clean_yum_uuid
+_clean_logins
+
+exit 0
diff --git a/packer/files/scripts/windows/cleanup.ps1 b/packer/files/scripts/windows/cleanup.ps1
new file mode 100644
index 0000000..6242ac5
--- /dev/null
+++ b/packer/files/scripts/windows/cleanup.ps1
@@ -0,0 +1,132 @@
+$ErrorActionPreference = "SilentlyContinue"
+Set-MpPreference -DisableRealtimeMonitoring $true -ErrorAction SilentlyContinue | Out-Null
+
+try {
+ $System = GWMI Win32_ComputerSystem -EnableAllPrivileges
+ $System.AutomaticManagedPagefile = $False
+ $System.Put() | Out-Null
+ $CurrentPageFile = gwmi -query "select * from Win32_PageFileSetting where name='c:\\pagefile.sys'"
+ $CurrentPageFile.InitialSize = 512
+ $CurrentPageFile.MaximumSize = 512
+ $CurrentPageFile.Put() | Out-Null
+
+ Write-Host "[INFO] Changed pagefile size"
+} catch {
+ Write-Host "[ERR] Error occured while attempting to modify pagefile size"
+ Write-Host "$($_.Exception.Message)"
+}
+
+try {
+ DISM /Online /Cleanup-Image /StartComponentCleanup /ResetBase /Quiet
+ Write-Host "[INFO] Executed dism to cleanup image and reset"
+} catch {
+ Write-Host "[ERR] Error occured while running dism to cleanup image and reset"
+ Write-Host "$($_.Exception.Message)"
+}
+
+try {
+ Remove-Item -Path "C:\Recovery" -Recurse -Force
+ Get-ChildItem "C:\Windows\SoftwareDistribution\*" -Recurse -Force | Remove-Item -Recurse -Force | Out-Null
+ Get-ChildItem "C:\Windows\SoftwareDistribution\*" -Recurse -Force | Remove-Item -Recurse -Force | Out-Null
+ Get-ChildItem "C:\Users\*\AppData\Local\Temp\*" -Recurse -Force | Remove-Item -Recurse -Force | Out-Null
+ Get-ChildItem "C:\Users\*\AppData\Local\Microsoft\Windows\Temporary Internet Files\*" -Recurse -Force | Remove-Item -Recurse -Force | Out-Null
+ Get-ChildItem "C:\ProgramData\Microsoft\Windows\Start Menu\Programs" -Recurse -Filter *uninstall*.lnk | % { Remove-Item -Force $_.FullName | Out-Null }
+
+ @(
+ "$env:localappdata\Nuget",
+ "$env:localappdata\temp\*",
+ "$env:windir\logs",
+ "$env:windir\panther",
+ "$env:windir\temp\*",
+ "$env:windir\winsxs\manifestcache"
+ ) | ForEach-Object {
+ if ((Test-Path $_) -And ($_ -NotLike "*.ps1")) {
+ try {
+ Takeown /d Y /R /f $_ 2>&1 | Out-Null
+ Icacls $_ /GRANT:r administrators:F /T /c /q 2>&1 | Out-Null
+ Remove-Item $_ -Recurse -Force | Out-Null
+ }
+ catch { $global:error.RemoveAt(0) }
+ }
+ }
+
+ Write-Host "[INFO] Removed temporary and build files"
+} catch {
+ Write-Host "[ERR] Error occured while attempting to remove temporary and build files"
+ Write-Host "$($_.Exception.Message)"
+}
+
+try {
+ & defrag.exe C: /h *> $null
+ Write-Host "[INFO] Executed defrag.exe"
+}
+catch {
+ Write-Host "[ERR] Error occured while running defrag.exe"
+ Write-Host "$($_.Exception.Message)"
+}
+
+try {
+ & cleanmgr.exe /verylowdisk *> $null
+ Write-Host "[INFO] Executed cleanmgr.exe"
+}
+catch {
+ Write-Host "[ERR] Error occured while running cleanmgr.exe"
+ Write-Host "$($_.Exception.Message)"
+}
+
+try {
+ $FilePath = "C:\zero.tmp"
+ $Volume = Get-WmiObject win32_logicaldisk -filter "DeviceID='C:'"
+ $ArraySize = 64kb
+ $SpaceToLeave = $Volume.Size * 0.05
+ $FileSize = $Volume.FreeSpace - $SpaceToLeave
+ $ZeroArray = New-Object byte[]($ArraySize)
+
+ $Stream = [IO.File]::OpenWrite($FilePath)
+ try {
+ $CurFileSize = 0
+ while ($CurFileSize -lt $FileSize) {
+ $Stream.Write($ZeroArray, 0, $ZeroArray.Length)
+ $CurFileSize += $ZeroArray.Length
+ }
+ }
+ finally {
+ if ($Stream) {
+ $Stream.Close()
+ }
+ }
+
+ Remove-Item $FilePath
+
+ Write-Host "[INFO] Zeroed out empty space"
+} catch {
+ Write-Host "[ERR] Error occured while attempting to zero out empty space"
+ Write-Host "$($_.Exception.Message)"
+}
+
+try {
+ powercfg /change monitor-timeout-ac 0
+ powercfg /change monitor-timeout-dc 0
+ powercfg /change disk-timeout-ac 0
+ powercfg /change disk-timeout-dc 0
+ powercfg /change standby-timeout-ac 0
+ powercfg /change standby-timeout-dc 0
+ powercfg /change hibernate-timeout-ac 0
+ powercfg /change hibernate-timeout-dc 0
+
+ Write-Host "[INFO] Disabled screen timeout, disk timeout, standby, hibernate"
+} catch {
+ Write-Host "[ERR] Error occured while attempting to modify screen timeout, disk timeout, standby, hibernate"
+ Write-Host "$($_.Exception.Message)"
+}
+
+try {
+ Clear-EventLog -LogName (Get-EventLog -List).log
+ Clear-EventLog -LogName (Get-EventLog -List).log
+ Clear-EventLog -LogName (Get-EventLog -List).log
+
+ Write-Host "[INFO] Cleared out event logs"
+} catch {
+ Write-Host "[ERR] Error occured while clearing event logs"
+ Write-Host "$($_.Exception.Message)"
+}
diff --git a/packer/files/scripts/windows/disable-updates.ps1 b/packer/files/scripts/windows/disable-updates.ps1
new file mode 100644
index 0000000..69d6441
--- /dev/null
+++ b/packer/files/scripts/windows/disable-updates.ps1
@@ -0,0 +1,13 @@
+# https://learn.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-automaticupdatesnotificationlevel
+# https://learn.microsoft.com/en-us/archive/blogs/jamesone/managing-windows-update-with-powershell
+try {
+ $updates = (New-Object -ComObject "Microsoft.Update.AutoUpdate").Settings
+ if ($updates.ReadOnly -eq $true) {
+ Write-Error "[ERR] Cannot update Windows Update settings due to GPO restrictions"
+ } else {
+ $updates.NotificationLevel = 1
+ $updates.Save()
+ $updates.Refresh()
+ Write-Output "[INFO] Automatic Windows Updates disabled"
+ }
+} catch { Write-Output "[ERR] Exception while disabling Automatic Windows Updates" }
diff --git a/packer/files/scripts/windows/enable-winrm-http.ps1 b/packer/files/scripts/windows/enable-winrm-http.ps1
new file mode 100644
index 0000000..44d8e70
--- /dev/null
+++ b/packer/files/scripts/windows/enable-winrm-http.ps1
@@ -0,0 +1,29 @@
+Get-NetConnectionProfile | Set-NetConnectionProfile -NetworkCategory Private
+
+New-ItemProperty `
+ -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System' `
+ -Name LocalAccountTokenFilterPolicy `
+ -Value 1 `
+ -Force | Out-Null
+
+winrm quickconfig -q
+winrm quickconfig -transport:http
+winrm set winrm/config '@{MaxTimeoutms="1800000"}'
+winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="800"}'
+winrm set winrm/config/service '@{AllowUnencrypted="true"}'
+winrm set winrm/config/service/auth '@{Basic="true"}'
+winrm set winrm/config/service/auth '@{CredSSP="true"}'
+winrm set winrm/config/listener?Address=*+Transport=HTTP '@{Port="5985"}'
+Start-Process -FilePath C:\Windows\System32\cmd.exe -ArgumentList "/c sc.exe config WinRM start= delayed-auto" -Wait -Verbose
+Start-Process -FilePath C:\Windows\System32\cmd.exe -ArgumentList "/c sc.exe stop WinRM" -Wait -Verbose
+Start-Process -FilePath C:\Windows\System32\cmd.exe -ArgumentList "/c sc.exe start WinRM" -Wait -Verbose
+
+New-NetFirewallRule `
+ -DisplayName WINRM-HTTP-In-TCP `
+ -Direction Inbound `
+ -Action Allow `
+ -Protocol TCP `
+ -LocalPort 5985 | Out-Null
+
+#netsh advfirewall firewall set rule group="Windows Remote Administration" new enable=yes
+#netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" new enable=yes action=allow remoteip=any
diff --git a/packer/files/scripts/windows/init.ps1 b/packer/files/scripts/windows/init.ps1
new file mode 100644
index 0000000..3eea7b4
--- /dev/null
+++ b/packer/files/scripts/windows/init.ps1
@@ -0,0 +1,25 @@
+Get-WmiObject Win32_UserAccount -Filter "Name='packer'" | % { $_.PasswordExpires = $false; $_.Put() } | Out-Null
+
+if ((Get-WmiObject -Class Win32_OperatingSystem).ProductType -ne 1) {
+ Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "DisableCAD" -Value 1 -Force
+
+ secedit /export /cfg C:\secpol.cfg
+ (Get-Content C:\secpol.cfg).replace("PasswordComplexity = 1", "PasswordComplexity = 0") | Out-File C:\secpol.cfg
+ (Get-Content C:\secpol.cfg).replace("MinimumPasswordLength = 7", "MinimumPasswordLength = 0") | Out-File C:\secpol.cfg
+ secedit /configure /db C:\Windows\security\local.sdb /cfg C:\secpol.cfg /areas SECURITYPOLICY
+ Remove-Item -Force C:\secpol.cfg -Confirm:$false
+}
+
+[Microsoft.Win32.Registry]::SetValue("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Power", "HiberFileSizePercent", 0)
+[Microsoft.Win32.Registry]::SetValue("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Power", "HibernateEnabled", 0)
+[Microsoft.Win32.Registry]::SetValue("HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Reliability", "ShutdownReasonOn", 1)
+[Microsoft.Win32.Registry]::SetValue("HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows NT\Reliability", "ShutdownReasonUI", 2)
+[Microsoft.Win32.Registry]::SetValue("HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge", "HideFirstRunExperience", 1)
+[Microsoft.Win32.Registry]::SetValue("HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU", "NoAutoRebootWithLoggedOnUsers", 1)
+[Microsoft.Win32.Registry]::SetValue("HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU", "IncludeRecommendedUpdates", 0)
+[Microsoft.Win32.Registry]::SetValue("HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU", "AUOptions", 2)
+[Microsoft.Win32.Registry]::SetValue("HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Edge", "HideFirstRunExperience", 1)
+[Microsoft.Win32.Registry]::SetValue("HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU", "NoAutoRebootWithLoggedOnUsers", 1)
+[Microsoft.Win32.Registry]::SetValue("HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU", "IncludeRecommendedUpdates", 0)
+[Microsoft.Win32.Registry]::SetValue("HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\AU", "AUOptions", 2)
+
diff --git a/packer/files/scripts/windows/setup-qemu-guest-agent.ps1 b/packer/files/scripts/windows/setup-qemu-guest-agent.ps1
new file mode 100644
index 0000000..a2baefa
--- /dev/null
+++ b/packer/files/scripts/windows/setup-qemu-guest-agent.ps1
@@ -0,0 +1,14 @@
+[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
+
+try {
+ $url = "https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/latest-virtio/virtio-win-guest-tools.exe"
+ (New-Object System.Net.WebClient).DownloadFile($url, "C:\virtio-win-guest-tools.exe")
+ Write-Output "[INFO] Downloaded $url"
+
+ Start-Process -FilePath "C:\virtio-win-guest-tools.exe" -ArgumentList "/install /passive /norestart" -Wait -Verbose
+ Write-Output "[INFO] Successfully installed VirtIO Guest Tools"
+ Remove-Item "C:\virtio-win-guest-tools.exe" -Force
+} catch {
+ Write-Host "[ERR] Error occured while installing VirtIO Guest Tools"
+ Write-Host "$($_.Exception.Message)"
+}
diff --git a/packer/files/scripts/windows/sysprep-shutdown.bat b/packer/files/scripts/windows/sysprep-shutdown.bat
new file mode 100644
index 0000000..623820a
--- /dev/null
+++ b/packer/files/scripts/windows/sysprep-shutdown.bat
@@ -0,0 +1,6 @@
+@echo off
+for %%i in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do (
+ if exist %%i:\sysprep.xml (
+ call C:\Windows\System32\Sysprep\sysprep.exe /generalize /oobe /unattend:%%i:\sysprep.xml /shutdown
+ )
+)