################################# #Configure variables here# ################################# $taskname = "UpdateAutoDesk" $Shortcutname = "UpdateAutoDesk" $Link = "C:\Users\Public\Desktop\$Shortcutname.lnk" $iconlocation = "C:\Windows\System32\CustomInstallExec.exe" $serviceui = "https://call4cloud.nl/wp-content/uploads/2021/07/ServiceUI.zip" $PowerShellScript = "C:\ProgramData\CustomScripts\UpdatingApps.ps1" ####################################################################################### #PowerShell Script need to output it to a file max 8190 as encoded command :( # ####################################################################################### $content = @' ######Configure variables here###### $appname = "AUTODESK" $downloadlocation = "C:\temp\$appname" $allowedpublisher = "O=AUTODESK, INC., L=SAN RAFAEL, S=CALIFORNIA, C=US" $allowedpublisher2 = "O=AUTODESK, INC, L=SAN FRANCISCO, S=CALIFORNIA, C=US" $allowedpublisher3 = "O=AUTODESK, INC, L=SAN RAFAEL, S=CALIFORNIA, C=US" $files = Get-ChildItem -path $downloadlocation -recurse -file "*.exe" | % { $_.FullName } Get-ChildItem -Path $downloadlocation -Recurse | Unblock-File ####preparing toast notifications ##### [reflection.assembly]::loadwithpartialname("System.Windows.Forms") [reflection.assembly]::loadwithpartialname("System.Drawing") $PSpath = Get-Process -id $pid | Select-Object -ExpandProperty Path $icon = [System.Drawing.Icon]::ExtractAssociatedIcon($PSpath) $notify = new-object system.windows.forms.notifyicon $notify.icon = $icon $notify.visible = $true $title4 = "Updates for $appname Failed" $message4 = "No files for $appname are found in the $downloadlocation" $title6 = "Pending Reboots!" $message6 = "Please Reboot your device first before installing updates" ###Check if reboot status is false otherwise quit ###### $rebootstatus = test-pendingreboot -SkipConfigurationManagerClientCheck $rebootstatus = $rebootstatus.isrebootpending if ($rebootstatus -eq $True) { $notify.showballoontip(50,$title6,$Message6,[system.windows.forms.tooltipicon]::info) exit } ####starting update process ##### ###checking if there are files. if not exit and show toast###### if ($files -eq $null) { $notify.showballoontip(50,$title4,$Message4,[system.windows.forms.tooltipicon]::info) exit }else { foreach ($file in $files) { ###creating toast messages ###### $outputFile = Split-Path $file -leaf $title1 = "Updates for $appname are being installed" $message1 = "App $outputfile will now be updated" $title2= "Updating $outputfile succeeded " $message2 = "Updates for the app $outputfile are installed succesfully" $title5= "Verifying $outputfile FAILED! " $message5 = "$outputfile could not be verified" $path = $file| % { $_.FullName } ###Check if publisher matches, if so install the update. If not show error code###### $publisher = (Get-AppLockerFileInformation -path $file).Publisher if (($publisher.PublisherName -eq $allowedpublisher) -or ($publisher.PublisherName -eq $allowedpublisher2) -or ($publisher.PublisherName -eq $allowedpublisher3)) { $notify.showballoontip(50,$title1,$Message1,[system.windows.forms.tooltipicon]::info) ###Starting process, cache it and wait for the exit code###### $proc = Start-Process -FilePath $file -PassThru $handle = $proc.Handle $proc.WaitForExit(); }else { start-sleep -s 10 $notify.showballoontip(50,$title5,$Message5,[system.windows.forms.tooltipicon]::info) start-sleep -s 5 } ###detect exit code and show toast###### $exitcode = $proc.exitcode if($proc.ExitCode -ne 0) { $title3 = "Update failed ERROR: $exitcode" $message3 = "Updates for $outputfile are not installed!" $notify.showballoontip(50,$title3,$Message3,[system.windows.forms.tooltipicon]::info) start-sleep -s 10 }else { start-sleep -s 10 $notify.showballoontip(50,$title2,$Message2,[system.windows.forms.tooltipicon]::info) start-sleep -s 5 Remove-Item $file -Recurse } } } '@ ######################################## #Output the PowerShell script to a file# ######################################## # create custom folder and write PS script $path = $(Join-Path $env:ProgramData CustomScripts) if (!(Test-Path $path)) { New-Item -Path $path -ItemType Directory -Force -Confirm:$false } Out-File -FilePath $powershellscript -Encoding unicode -Force -InputObject $content -Confirm:$false ################################# #Download and install ServiceUI.exe# ################################# $path = "C:\program files (x86)\service" if (!(Test-Path $path)) { New-Item -Path $path -ItemType Directory -Force -Confirm:$false Invoke-WebRequest $serviceui -OutFile "$path\ZippedFile.zip" Expand-Archive -LiteralPath "$path\ZippedFile.zip" -DestinationPath "$path" -force } ################################# #install powershell modules# ################################# if (Get-PackageProvider -ListAvailable -Name NuGet) { Write-Host "Module exists" }else { Install-PackageProvider -Name NuGet -force } if (Get-Module -ListAvailable -Name PendingReboot) { Write-Host "Module exists" }else { Install-module -Name PendingReboot -force } ####################################################################################################### ####Install the Update task part! # # v.1.1 Added %comspec% cmd /c start /min to hide the powershell windows a little bit more # ####################################################################################################### $triggers = New-ScheduledTaskTrigger -Once -At (get-date).AddSeconds(-200); $triggers.EndBoundary = (get-date).AddSeconds(-100).ToString('s') $Action = New-ScheduledTaskAction -Execute "c:\program files (x86)\service\ServiceUI.exe" -argument "-process:explorer.exe %SYSTEMROOT%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -file $powershellscript" $settings = New-ScheduledTaskSettingsSet -StartWhenAvailable $Null = Register-ScheduledTask -TaskName $taskname -Trigger $triggers -User "SYSTEM" -Action $Action -Settings $Settings -Force ############################################################################ ####Change Permissions for the task ! # ########################################################################### $scheduler = New-Object -ComObject "Schedule.Service" $scheduler.Connect() $task = $scheduler.GetFolder("\").GetTask($taskname) $sec = $task.GetSecurityDescriptor(0xF) $sec = $sec + '(A;;GRGX;;;AU)' #PLEASE NOTE GRGX --> 1179817 # $task.SetSecurityDescriptor($sec, 0) #################################################### ##### Create Shortcut to task on Desktop ! # ################################################### if (-not (Test-Path $Link)) { $null = $WshShell = New-Object -comObject WScript.Shell $targetpath = "C:\Windows\System32\schtasks.exe" $Shortcut = $WshShell.CreateShortcut($Link) $Shortcut.TargetPath = $targetpath $Shortcut.Arguments = "/run /TN $taskname" $Shortcut.IconLocation = $IconLocation $Shortcut.Save() } #################################################### ##### Remove Users from powershell script ! # ################################################### $path = $powershellscript #breaks inheritence $acl = (Get-Item $path).GetAccessControl('Access') $acl.SetAccessRuleProtection($true,$true) set-acl $path -AclObject $acl #removes all access rules based on 'BUILTIN\Users' $acl = (Get-Item $path).GetAccessControl('Access') $acl.Access |where {$_.IdentityReference -eq 'BUILTIN\Users'} |%{$acl.RemoveAccessRule($_)} set-acl $path -AclObject $acl