I have been tasked with compiling a list which contains the version and last successful auto update for all the machines on the domain.
I understand this would be much easier if I used the Sophos enterprise console but unfortunately this is not a resource that is available to me at this time.
So far I have created a PowerShell script which currently gives me back the current Sophos version, computer name, and the exe file. However I am now struggling to find a way to also display the date and time of the last successful auto update. the domain is set up to auto update every 10 minuets.
PowerShell Script :
function Get-AntiVirusProduct {
[CmdletBinding()]
param (
[parameter(ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)]
[Alias('name')]
$computername=$env:computername
)
$AntiVirusProduct = Get-WmiObject -Namespace "root\SecurityCenter2" -Class AntiVirusProduct -ComputerName $computername
#Create hash-table for each computer
$ht = #{}
$ht.'Computername' = $computername
$ht.Name = $AntiVirusProduct.displayName
$ht.'Product Executable' = $AntiVirusProduct.pathToSignedProductExe
$ht.'Version' = [System.Diagnostics.FileVersionInfo]::GetVersionInfo ("C:\Program Files (x86)\Sophos\AutoUpdate\ALUpdate.exe").FileVersion
#Create a new object for each computer
New-Object -TypeName PSObject -Property $ht
}
Get-AntiVirusProduct
I have done some research and seen where a K100 script has been used to query the auto update file but I am not sure if this would be applicable for my solution.
FileExists(C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe) AND ShellCommandTextReturn(cmd /q /c powershell.exe -command "$f=[DATETIME] '01/01/1970 00:00:00'; $f.AddSeconds((Get-ItemProperty -Path 'REGISTRY::HKLM\SOFTWARE\Sophos\AutoUpdate\UpdateStatus' LastUpdateTime).LastUpdateTime) | ForEach-Object {'{0:yyyy}-{0:MM}-{0:dd} {0:HH}:{0:mm}:{0:ss}' -f ($_.AddHours(-0))}")
The module which the update runs to is ALUpdate.exe
would appreciate any help or suggestions.
Sophos Bootable Anti-Virus (SBAV) is an antivirus tool that will allow you to perform scanning and cleaning of the infected computer without the need to install the software. This procedure will be useful when the Master Boot Record (MBR) is infected on your computer.
The Sophos Bootable Antivirus is provided for free as a Windows binary file .exe file. You can download the program to the Windows computer and then install it. Once the installation is done, you have to run a command. The program will now create an ISO file with the latest version of the Sophos Antivirus including the recent virus protection updates. The tool will boot the computer using the underlying Linux operating system and performs a scan of the computer by suppressing the local operating system.
There are practically two different methods in which you can create the Sophos Bootable Antivirus:
By using a Bootable CD
By using a Bootable USB stick
Creating a bootable CD
Double-click on the bootable downloaded sbav_sfx file.
Click Accept to the License agreement and later on specify the installation location (default location is C:\SBAV). Take note of the specified location.
Open the command prompt.
You can open the Run command by pressing the Windows + R button on the keyboard.
Type cmd then press the Enter button.
Related
I'm trying to create a script on a Flashdrive to run several commands on all of our company computers. In this specific part I'm trying to run commands for AVAST to run a virus scan and do updates at 10 pm. The problem i'm running into is: in order to run these commands I have to navigate to the folder where the Avast software is. Thing is the drive letter might vary per computer.... so I'm not sure if I'm able to use a wildcard or how I would go about this. My current script is:
echo off
cd "$((get-location).drive.name):\Program Files (x86)\Avast Software"
ashupd.exe/vps
ashupd.exe/program
ashcmd.exe/*
pause
This only gets the current drive letter... which would be the flashdrive I'm running the script off of. So that's no good.
I have this little test saved for when I need to trying both 32bit and 64bit paths.
$var = Get-WmiObject win32_operatingsystem
if ($var.osarchitecture -like "64*") {
#64 bit logic here
$path = \path\to\64x\
}
else {
#32 bit logic here
$path = \path\to\86x\
}
I am trying to Install windows security patches on a remote machine using powershell remoting.
This is the function i am using to Update windows
<#
.SYNOPSIS
This functiion will automatically install all avaialable windows updates on a device and will automatically reboot if needed, after reboot, windows updates will continue to run until no more updates are available.
#>
function Install-WindowsUpdates
{
Install-Module -Name PSWindowsUpdate -RequiredVersion 2.1.0.1 -Force
Import-Module PSWindowsUpdate -Force
Get-WindowsUpdate -install -acceptall
}
When i run this function on a local host, the function is successful in installing windows security patches. I have the below script to do the same remotely:
param(
[Parameter(Mandatory = $true)]
[string] $IPaddress
)
try
{
$secpasswd = ConvertTo-SecureString "Pass#12345678" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ("Admin02", $secpasswd)
#Create a Session.
$Session = New-PSSession -ComputerName $IPaddress -Credential $cred
cd C:\Users\Admin01\Documents
. .\Install-WindowsUpdates.ps1
Invoke-Command -Session $Session -ScriptBlock ${function:Install-WindowsUpdates}
return $true
}
catch
{
return $false
}
When i run this script i am getting the below error:
Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
+ CategoryInfo : NotSpecified: (:) [Get-WindowsUpdate], UnauthorizedAccessException
+ FullyQualifiedErrorId : System.UnauthorizedAccessException,PSWindowsUpdate.GetWindowsUpdate
+ PSComputerName : 10.0.0.7
I have setup both the loaclhost and remote machine for remoting and able to execute other scripts remotely. Also have enabled WMI on the remote machine.
What other settings i have to do?
Using Scheduled Task:
I am using the following script to start a scheduled task:
param(
[parameter(Mandatory = $true)]
[string]$IPaddress
)
$PSModulePath = $env:PSModulePath
$SplittedModulePath = $PSModulePath.Split(";")
$ModulePath = $SplittedModulePath[0]
$secpasswd = ConvertTo-SecureString "Pass#12345678" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ("Admin02", $secpasswd)
#Create a Session. Replace host name with the host name of the remote machine.
$Session = New-PSSession -ComputerName $IPaddress -Credential $cred
$User= "Admin02"
$Action= New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "$env:ALLUSERSPROFILE\Install-WindowsUpdate.ps1"
$Trigger= New-ScheduledTaskTrigger -At 5:05am -Once
Invoke-Command -Session $Session -ScriptBlock { Register-ScheduledTask -TaskName "Install-Updates" -User $Using:User -Action $Using:Action -Trigger $Using:Trigger -RunLevel Highest –Force }
I have copied the below script on the target machine at the path $env:ALLUSERSPROFILE
<#
.SYNOPSIS
This functiion will automatically install all avaialable windows updates on a device and will automatically reboot if needed, after reboot, windows updates will continue to run until no more updates are available.
.PARAMETER computer
Use the Computer parameter to specify the Computer to remotely install windows updates on.
#>
Install-Module -Name PSWindowsUpdate -RequiredVersion 2.1.0.1 -Force
Import-Module PSWindowsUpdate -Force
Get-WindowsUpdate -install -acceptall
After i schedule the task nothing is happening.What i am doing wrong?
Yea, I fought this for weeks and finally have a good solution. The solution is actually built right into the PSWindowsUpdate module. The built in solution does use a windows Task, but it launches right away, and its actually helpful in tracking its completion progress, and it keeps the integration secure. The issue I have found is that PSWindowsUpdate has poor documentation. The following code worked for me:
Invoke-WUJob -ComputerName $svr -Script {ipmo PSWindowsUpdate; Get-WUInstall -AcceptAll -AutoReboot -Install | Out-File C:\PSWindowsUpdate.log } -Confirm:$false -Verbose -RunNow
There is a lot of scattered information on this topic, so please do your reading. PSWindowsUpdate is by far the best library for this job, and although its been a long process for me, I believe the above solution will work for everyone.
Please remember, the computer you are running the above scrip from needs to trust the computer you are trying to update, you can run this script to trust the computer:
Set-Item WSMan:\localhost\Client\TrustedHosts -Value <ComputerName>
NOTE: Wildcards can be used in computer name
I also wanted to give you some information that greatly helped me:
Get-WindowsUpdate: This is the main cmdlet of the module. It lists, downloads, installs or hides a list of updates meeting predefined requisites and sets the rules of the restarts when installing the updates.
Remove-WindowsUpdate: Uninstalls an update
Add-WUServiceManage: Registers a new Windows Update API Service Manager
Get-WUHistory: Shows a list of installed updates
Get-WUSettings: Gets Windows Update client settings
Get-WUInstallerStatus: Gets Windows Update Installer Status, whether it is busy or not
Enable-WURemoting: Enables firewall rules for PSWindowsUpdate remoting
Invoke-WUJob: Invokes PSWindowsUpdate actions remotely
Like for all PowerShell cmdlets, different usage examples can be shown for each command typing Get-Help “command” -examples.
PSWindowsUpdate main parameters
As shown in the previous section, the PSWindowsUpdate module includes different predefined aliases to ease patching processes. However, main parameters for the Get-WindowsUpdate cmdlet will be listed and explained below:
Filtering updates:
AcceptAll: Downloads or installs all available updates
KBArticleID: Finds updates that contain a KBArticleID (or sets of KBArticleIDs)
UpdateID: Specifies updates with a specific UUID (or sets of UUIDs)
Category: Specifies updates that contain a specified category name, such as ‘Updates,’ ‘Security Updates’ or ‘Critical Updates’
Title: Finds updates that match part of title
Severity: Finds updates that match part of severity, such as ‘Important,’ ‘Critical’ or ‘Moderate’
UpdateType: Finds updates with a specific type, such as ‘Driver’ and ‘Software.’ Default value contains all updates
Actions and targets:
Download: downloads approved updates but does not install them
Install: installs approved updates
Hide: hides specified updates to prevent them to being installed
ScheduleJob: specifies date when job will start
SendReport: sends a report from the installation process
ComputerName: specifies target server or computer
Client restart behavior:
AutoReboot: automatically reboots system if required
IgnoreReboot: suppresses automatic restarts
ScheduleReboot: specifies the date when the system will be rebooted.
#How to avoid accidental installs#
Windows updates and patches improve the features and stability of the system. However, some updates can mess up your system and cause instability, especially automatic updates for legacy software such as graphic card drivers. To avoid automatic updates and accidental installs for such applications, you can pause Windows updates.
Alternatively, you can hide the specific updates for those features you don’t want to get updated. When you hide the updates, Windows can no longer download and install such updates. Before you can hide the update, you need to find out its details, including its knowledge base (KB) number and title. Type the cmdlet below to list all the available updates on your system:
Get-WUList
To hide a specific update using the KB number, use your mouse to copy that KB number. Next, type the command below:
Hide-WUUpdate -KBArticleID KB_Number
Highlight the “KB_Number” and click paste to replace that part with the actual KB number.
When prompted to confirm the action, type A, and hit the Enter key. If the command succeeds, the “Get-WUList” lists all the available updates, with hidden updates appearing with the symbol “H” under their status.
The KB number for the update may not be available for some updates. In this case, you can use the title to hide the update. To do this, list all the available updates via the cmdlet below:
Get-WUList
Next, use your mouse to copy the update title. Ensure it is distinct from other update titles. Now, type below command below to hide the update:
Hide-WUUpdate -Title “Update_Title”
Don’t forget to paste the actual update title in the “Update Title” section.
When prompted to confirm the action, type A, and hit the Enter key. If the command succeeds, the “Get-WUList” lists all the available updates. However, the status of hidden updates appears with the symbol “H” underneath them.
How to determine errors
It is of crucial importance to have as much information as possible about Windows Updates installation processes in order to be able to fix erroneous deployments. The Get-WindowsUpdate cmdlet and the rest of cmdlets available in the module, provide a very detailed log level when managing updates, including status, KB ID, Size or Title.
Centralizing all of the computer logs and analyzing them searching for errors, administrators will always be able to know the patch level of their Windows computers and servers.
The above passages came from this site!
This seems to be not possible by design:
Source 1
Source 2
Source 3
It is impossible for remotely connected users to download stuff from the internet it appears.
Speaking about windows update, you have many options like:
Connection using psexec tool then run wuauclt /detectnow /updatenow
If you are using windows 10 /server 2016 , the tools was replaced with USOClient.exe which is more effective.
When I upgrade / downgrade my application via a Powershell script, I want to first force the uninstallation of the currently installed version before running the new installer.
How can I do that with Powershell, using the UpgradeCode of the application?
Doing it by application name would be less robust.
Since you mention upgrade code, it must mean that you are talking about an MSI file (Windows Installer). As stated by others such an uninstall is normally performed auto-magically by a properly authored MSI package - it is referred to as a major upgrade - which is essentially an uninstall of the existing version of a product and then the install of the newest version.
The Upgrade Table of the MSI being installed will specify what existing packages on the box will be uninstalled before the new version is installed. In theory you can uninstall any number of existing installations. You can even uninstall a competitive product if you are mad as a hatter. Frankly, and astonishingly, I have never tried to uninstall multiple products during one major upgrade - it is rarely called for. In most cases you uninstall a single, existing product and then install your latest version.
You can modify the Upgrade table using a transform to change how the major upgrade behaves - in other words to make it start or stop uninstalling a specific pre-existing installation.
You can also enumerate all related products that share the same upgrade code by calling this MSI API function (COM - VBScript used as sample):
Set installer = CreateObject("WindowsInstaller.Installer")
' Enumerate all products related to "Microsoft Visual C++ 2008 Redistributable - x86 9.0.30729.4148"
' {AA783A14-A7A3-3D33-95F0-9A351D530011} is the upgrade code
Set upgrades = installer.RelatedProducts("{AA783A14-A7A3-3D33-95F0-9A351D530011}")
For Each u In upgrades
MsgBox u, vbOKOnly, "Product Code: "
Next
Then you can uninstall the products by passing the product code(s) to the msiexec.exe command line (see below for how to do this via MSI API COM automation instead):
msiexec.exe /x {11111111-1111-1111-1111-11111111111X} /L*V "C:\msilog.log" REBOOT=ReallySuppress
Quick Parameter Explanation (since I recommend this option):
/X = run uninstall sequence
/QN = run completely silently
/L*V "C:\msilog.log"= verbose logging at path specified
{11111111-1111-1111-1111-11111111111X} = product guid of app to uninstall
REBOOT=ReallySuppress = prevent reboot without warning (badly authored MSI packages)
If you don't want to uninstall via msiexec.exe, then you can find a myriad of ways to invoke an MSI uninstall here:
Uninstalling an MSI file from the command line without using msiexec.
And you can find the product code of an installed MSI in several different ways: How can I find the product GUID of an installed MSI setup?
UPDATE: I guess I forgot the obvious, you can uninstall directly via MSI API automation. In the script below we get all products sharing the same upgrade code and then uninstall them in sequence.
Note that when run silently you should run with admin rights since the UAC may be suppressed and then the uninstall will usually fail (permission denied). Because of this the below script runs the uninstall interactively - allowing UAC prompting and elevation.
And if it isn't obvious: running this script will uninstall Orca! I use this product as a sample because it is quick to install again (hints on finding the installer quick if you need to towards bottom here - search for "orca"):
BIG DISCLAIMER:
The COM method installer.ConfigureProduct does not accept any arguments that allow us to pass in REBOOT=ReallySuppress. This means that a (very) badly authored package which triggers the ScheduleReboot action (or uses some more obscure magic to cause a reboot) - may reboot the system without warning if you run the below script with admin rights and in silent mode.
There is a newer call ConfigureProductEx which is available as a Win32 function, but it is not exposed via the COM automation interface. If you platform invoke you can use that call - there is a C++ example in section 14 here: Uninstalling an MSI file from the command line without using msiexec. Or you can use the DTF feature from the WiX toolkit (see section 6 in the same link as the C++ example).
UPDATE July 2018:
Set installer = CreateObject("WindowsInstaller.Installer")
installer.InstallProduct "product.msi", "REMOVE=ALL REBOOT=ReallySuppress"
Set installer = Nothing
Perhaps the above snippet is the best uninstall approach? This should suppress any reboots. I don't have the time or the setup to test it right now (on a Linux box), but I wanted to add it before I forget.
Original uninstall script:
Const msiUILevelNone = 2
Const msiInstallStateAbsent = 2
Set installer = CreateObject("WindowsInstaller.Installer")
'installer.UILevel = msiUILevelNone ' Disabled to prevent silent uninstall. Now the UAC prompt will show
' Uninstall Orca, replace upgrade code with yours
Set products = installer.RelatedProducts("{CFF4D510-79B2-1CCD-0061-5741A0565A76}")
For Each product In products
' MsgBox "Product Code: " & product ' Show the product code found, if you want
' The following call when run silently with admin rights may reboot the system without warning!
' This is due to badly authored MSI packages - most packages will not trigger this problem.
installer.ConfigureProduct product, 0, msiInstallStateAbsent ' Uninstall product
' See text above for info on the newer ConfigureProductEx method.
Next
Set installer = Nothing
MsgBox "Finished" ' Just so we know the script ran if nothing found to uninstall
Some Links:
Is there an alternative to GUID when using msiexec to uninstall an application? (uninstall by product name)
How can I uninstall an application using PowerShell?
How can I use powershell to run through an installer?
WIX (remove all previous versions)
Wix upgrade goes into maintenance mode and never does upgrade (various ways to uninstall, by product code, by upgrade code, etc...)
Since the question specifically mentions powershell I'll just put this here too. There are other PS solutions around using WMI and/or Get-Package. This solution is based off of https://outnull.wordpress.com/2016/11/02/uninstalling-application-based-on-upgradecode/ but accepts various forms of upgrade code syntax, and it tries to avoid string manipulation when converting to/from the package/upgrade Guid and the registry representation.
$upgradecode = "{CFF4D510-79B2-1CCD-0061-5741A0565A76}"
$installer = Join-Path -Path $env:SystemRoot -ChildPath "system32\msiexec.exe" -Resolve
function Reverse-Nibbles {
param ( [byte[]] $bytes )
# reverse nibbles of each byte
for($i = 0; $i -lt $bytes.Length; $i++ )
{
$bytes[$i] = (($bytes[$i] -band 0x0F0F) -shl 4) -bor (($bytes[$i] -band 0xF0F0) -shr 4)
}
Write-Output -NoEnumerate $bytes
}
function GuidToRegString {
param ( [guid] $guid )
$bigendian = (Reverse-Nibbles $guid.ToByteArray())
return [System.Runtime.Remoting.Metadata.W3cXsd2001.SoapHexBinary]::new($bigendian).ToString()
}
function RegStringToGuid {
param ( [string] $guid )
$littleendian = (Reverse-Nibbles ([System.Runtime.Remoting.Metadata.W3cXsd2001.SoapHexBinary]::Parse($guid).Value))
return [guid]::new($littleendian)
}
$upcode = GuidToRegString ([guid]::Parse($upgradecode))
if (Test-Path -Path "HKLM:\Software\Classes\Installer\UpgradeCodes\$upcode") {
$products = RegStringToGuid (Get-Item -Path "HKLM:\Software\Classes\Installer\UpgradeCodes\$upcode").Property
foreach ($prod in $products) {
$pguid = [guid]::new($prod)
$p = $pguid.ToString("B")
if ((Test-Path -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\$p") -or
(Test-Path -Path "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\$p"))
{
$logfile = Join-Path -Path $PSScriptRoot -ChildPath uninstall-$($pguid.ToString("D")).log
$args = #( "/x", $p, "/l*v", """$logfile""", "/q", "COMPLETE_UNINSTALL=1", "REBOOT=REALLYSUPPRESS" )
Write-Host "Uninstalling $p"
$uninst = Start-Process -FilePath """$installer""" -ArgumentList $args -PassThru -Wait
Write-Host $uninst.ExitCode
}
}
}
I'm verry beginer in powershell, I'm wonking in a project, the goal it's to set the Biossetting like disabling or enabling the secureBoot and UEFI mode, while installing windows 7 or 10 by MDT.
I'm working with Dell and hp computer, I have the script for setting the bios of hp or dell
Hp:
$bios=Get-WmiObject -Namespace root/hp/instrumentedBIOS -Class HP_BIOSSettingInterface
$bios.SetBIOSSetting("UEFI Boot Options", "Enable","")
Dell:
(Get-WmiObject DCIM_BIOSService -namespace root\dcim\sysman -ComputerName .).SetBIOSAttributes($null,$null,"Secure Boot","1")
Then, my first problem these command is not working in any computer I need to install some modules, some cmdlet from hp or dell website, I want to know if make my script ".exe", it's gonna work in every-computer ?
Because I need to run my script with with deployement of windows.
My second and difficult task, I want to know with variable task sequence to use in my script, to detect the os of the tasksequence, I find this code in internet, after too much research in internet
$TaskPath = "$($MdtDrive):\Task Sequences"
$ControlPath = "$MDtroot\Control"
$OSPath = "$($MdtDrive):\Operating Systems"
$OS = (Get-ChildItem -Path $OSPath | Out-GridView -PassThru -Title "Select required OperatingSystem").Name
This code detect if the OS of the task sequence I want install in my computer is windos 7 or windows 10?
Thanks !
If I recall correctly from my days of systems deployment, Dell and HP both make dedicated tools for settigns BIOS configuration. Just make sure you run it in WinPE. Depending on which BIOS settings you change you make even have to boot WinPE twice to make sure the OS installs the way you want.
Dell: http://en.community.dell.com/techcenter/enterprise-client/w/wiki/7532.dell-command-configure
HP: https://deploymentbunny.com/2010/10/18/enable-tpm-via-task-sequence-on-hp-boxes/
Although it is definitely possible to make these settings in WMI I would only look to it as a last resort. Windows has to be compatible with every piece of hardware, whereas Dell/HP tools are targeted at their systems. It's like using a scalpel vs a Swiss army knife.
I have some difficults I’m working in a script who set the bios configuration while installing windows 7 or 10 by MDT, then my first question is:
Wich variable I can use to identify the os of the new task sequence I mean the current os the mdt preparing to install in the computer after the user select the os during the installation.
I’m wondering if this code doying the job
$OS = Get-ChildItem -Path $OSPath | Out-GridView -PassThru -Title “Select required OperatingSystem”
$OSPath = “$($MdtDrive):\Operating Systems”
We have a program running on about 400 PCs (All W7). This program is called Wisa.
We receive regular updates for this program, named something like wisa_update1.0.exe, wisa_update1.1.exe, wisa_update2.0.exe, etc. The users can not do the update themself due to account restrictions.
We manage to do the update once and distribute it with a copy-item to all PCs. Then with Enter-PSSession I can go to each PC and update the program with the following command:
wisa_update3.0 /verysilent
(with the argument /verysilent no questions are asked)
This is already a major gain in time, but I want to do the update more automatically.
I have a file "pc.txt" with all 400 PCs in it. I use this file already for the Copy-Item via Get-Content. Now I want to use this file to do the updates with the above command, but I can't find a good way to use a remote executable with a parameter in PowerShell.
What you want to do is load get-content -Path $PClist and then run your script actions in a foreach. You'll want to adapt this example to your own script:
$PClist = 'c:\pc.txt'
$aComputers = Get-Content -Path $PClist
foreach ($Computer in $aComputers)
{
code actions to perform
}
Also you can use multithreading and get it over with fraction of time (provided you have a good machine). The below mentioned link explains how to do it well.
http://www.get-blog.com/?p=22