I had written a PowerShell script to download and install windows updates as follows. This script will run powershell to run as administrator. I run on a windows 7 computer but it keep having a loop of opening the powershell windows. pls advise
enter code here
If (-NOT ([Security.Principal.WindowsPrincipal]
[Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole
([Security.Principal.WindowsBuiltInRole] "Administrator")) {
$arguments = "& '" + $myinvocation.mycommand.definition + "'"
Start-Process powershell -Verb runAs -ArgumentList $arguments
#define type of updates
$criteria="Isinstalled=0 and Type='driver'"
#Search for relevant updates
$Searcher=New-Object -ComObject Microsoft.Update.Searcher
$SearchResult=$Searcher.Search($criteria).updates
if($SearchResult.Count -gt 0) {
$Session=New-Object -ComObject Microsoft.Update.Session
$Downloader=$Session.CreateUpdateDownloader()
$Downloader.Updates=$SearchResult
$Downloader.Download()
$installer=New-Object -ComObject Microsoft.Update.Installer
$installer.Updates=$SearchResult
$Install_Begin=$installer.Install()
}
break
}
to be honest, if you are trying to install updates from PowerShell you can do this from two easy lines of code.
The first would be to install the module for updates and the second would be to run the updates.
Please see the code below for updating windows.
install-module pswindowsupdate
Install-WindowsUpdate -MicrosoftUpdate -AcceptAll -AutoReboot
Related
So I am trying to write a script that will check if the user has a certain module installed, and if it doesn't, to install it, then rerun itself.
When I try to run this, the script just keeps rerunning and trying to install. I have to use a setup.exe and I have it waiting for the window to cl
$mypath = $MyInvocation.MyCommand.Path
$Path = Split-Path $mypath -Parent
$Location = "$Path" + "\setup.exe"
if (Get-Module -ListAvailable -Name ActiveRolesManagementShell) {
Write-Host "QAD Is installed"
pause
}
else{
Write-Host "Installing QAD"
Start-Process $Location
Wait-Process -Name "setup"
Pause
$CommandLine = "-File `"" + $MyInvocation.MyCommand.Path + "`" " + $MyInvocation.UnboundArguments
Start-Process -FilePath PowerShell.exe -Verb Runas -ArgumentList $CommandLine
Pause
}
Normally, modules are installed using Install-Module. Then you might need to tell PowerShell about it for the current session to be able to use it.
if (-not(Get-Module -ListAvailable -Name ActiveRolesManagementShell)) {
Install-Module ActiveRolesManagementShell
Import-Module ActiveRolesManagementShell # Might not be needed
}
# Add code that uses ActiveRolesManagementShell module
But with regards to ActiveRolesManagementShell, what version are you using?
The old Quest module was probably meant to work on PowerShell v2. And I can't find a current version...
Hi I currently have a very basic PowerShell script that runs when a computer is installed with Windows (any version). This script is below
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Unrestricted -Force
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
Write-Output "Installing OS Updater Modules Please Wait...."
Write-Output " "
Install-PackageProvider -Name NuGet -Force
Install-Module -Name PSWindowsUpdate -Force
Write-Output " "
Write-Output "Installing Updates...."
Write-Output " "
Install-WindowsUpdate -AcceptAll -Install -IgnoreReboot | Out-File "c:\temp\WindowsUpdate.log" -force
As I said very simple code this will install a few modules then update windows with any updates, however, it only works with PowerShell 5 and above is there a way I can check what version is installed then carry on with the script if it is PowerShell 4 and below stop executing the script.
I know it's possible to install Windows Management Framework 5.1 into the install.wim/esd which will get around this but for people who don't have this, I would like the script to stop and not have any errors.
u can use cmdlet named "get-host", it works in ps version >=2.0
if ((get-host).version.major -le 4)
{
#code
}
else
{
#code
}
or if u need exact match , u can use switch construction
switch ((get-host).version.major)
{
4 {#installcode4}
5 {#installcode5}
7 {#installcode7}
}
I have a script to uninstall McAfee antivirus and the agent associated with it.
The issue i'm having is that the script provides an exit code too early and doesn't continue through. If I run the script multiple times I get the desired result, but as we're trying to push it out via PDQ remotely, we need it to run through the script and only provide an exit code at the end of the script.
I'm a powershell novice so there's probably a much better and easier way to write this script but any advice would be greatly appreciated.
Start-Process -FilePath "msiexec.exe" -ArgumentList "/x {CE15D1B6-19B6-4D4D-8F43-CF5D2C3356FF} REMOVE=ALL REBOOT=R /q"; Write-Host "Uninstalling McAfee VirusScan Enterprise 8.8..."
$version = (Get-WmiObject -class Win32_OperatingSystem).Caption
Write-Host "Detected OS as $version"
if ($version -like '*Windows 7*')
{
Write-Host "Uninstalling McAfee Agent..."
Start-Process -FilePath "C:\Program Files (x86)\McAfee\Common Framework\frminst.exe" -ArgumentList "/forceuninstall"
}
elseif ($version -like '*Windows 10*')
{
Write-Host "Unmanaging McAfee Agent for Uninstall Process.."
Start-Process -FilePath "C:\Program Files\McAfee\Agent\maconfig.exe" -ArgumentList "/provision /unmanaged";
Write-Host "Uninstalling McAfee Agent..."
Start-Process -FilePath "C:\Program Files\McAfee\Agent\x86\frminst.exe" -ArgumentList "/forceuninstall"
}
else
{
exit
}
Start-Process reports a return code as soon as it starts the process indicating whether it was successful or not. Either use -wait to force the script to wait until it finishes or capture the output and proceed based on what the returnvalue is. See the docs for Start-Process
I'm trying to make a silent install of an AMD driver with Powershell, but for some reason, I always get the AMD installation screen.
My arguments seem to be ok because I do not have to click anywhere and the installation completes by itself.Is there any way to install it without any windows popping up? I can install 7zip silently the same way without any problem.
Set-ExecutionPolicy Unrestricted
$Logpath = 'C:\powershell.log'
function Install_app
{
$exe_to_execute = 'C:\Setup.exe'
$argument = '/unattended_install:"..\Packages\Drivers\Display\W76A_INF;..\Packages\Drivers\amdkmpfd\W764a;..\Packages\Apps\ACP64;..\Packages\Apps\AppEx;..\Packages\Apps\CCC2;..\Packages\Apps\CIM;..\Packages\Apps\VC12RTx64\" /autoaccept_all /force_hide_first_run /force_close_when_done /on_reboot_message:no'
$process = Start-Process -FilePath $exe_to_execute -ArgumentList $argument -Wait -PassThru -NoNewWindow
# Loop until process exits
do {start-sleep -Milliseconds 500}
until ($process.HasExited)
# Log results
$(Get-Date).ToString() + " Exit code " + $process.ExitCode | Out-File $Logpath -Append
}
Install_app
My script is in fact actually working as it is. The problem is that it will only hide all setup windows if run under the system account.
I have a quite a few computer systems which we need to deploy software. I've been using a simple method for detecting if a user is a local admin, then detecting if they have admin rights. If needed, the script relaunches with elevated privileges. If the user is not a local admin, the script relaunches using a different credentials (local admin). The script works great on systems which have a later version of PowerShell such as Windows 8 and Windows 10.
The problem is when the user is not an admin and the script is running on Windows 7. The script uses $PSScriptPath to relaunch the script. I don't think this works in earlier versions of PowerShell. So I tried setting $PSScriptRoot myself if the Major PowerShell version is < 3. The problem is then the script gets stuck in a loop of some sort where it just constantly opens and closes windows and then I have to kill it... If I don't define $PSScriptRoot I get the error
Cannot bind argument to parameter 'Path' because it is null
I assume this is because $PSScriptRoot isn't defined in PowerShell 2.0.
Here's an example of what I'm trying to do:
#Check if PowerShell version is greater than 2. If not, set $PSSriptRoot.
if ($PSVersionTable.PSVersion.Major -lt 3) {
$PSScriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Definition
}
#Check if the user is a local admin. If they are, set $LocalAdmin to $True.
$LocalAdmin = $false
if ((net localgroup administrators) -match ([System.Environment]::UserDomainName + "\\" + [System.Environment]::Username)) {
$LocalAdmin = $true
}
if ($LocalAdmin) {
#Check if the local admin needs to run the script as administrator
if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
$arguments = "& '" + $MyInvocation.MyCommand.Definition + "'"
Start-Process powershell -Verb runas -ArgumentList $arguments
break
}
} else {
#Not a local admin. Relaunch script as admin user.
Start-Process -Credential $credential (Join-Path $PSHome powershell.exe) -ArgumentList (#("-File",
(Join-Path $PSScriptRoot $MyInvocation.MyCommand)) + $args)
exit
}
Don't re-define automatic variables. Nothing good will come of it.
Besides, why do you want to anyway? The only thing you use $PSScriptRoot for is to reconstruct the script path you already have. Just assign that path to a variable and use that in your script.
$script = $MyInvocation.MyCommand.Definition
$ps = Join-Path $PSHome 'powershell.exe'
$isLocalAdmin = [bool]((net localgroup administrators) -match "$env:USERDOMAIN\\$env:USERNAME")
if ($isLocalAdmin) {
if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]'Administrator')) {
Start-Process $ps -Verb runas -ArgumentList "& '$script'"
exit
}
} else {
Start-Process $ps -ArgumentList (#('-File', $script) + $args) -Credential $credential
exit
}