silent installation using powershell - powershell

I am trying to install software using powershell silent scripting. To install this software we need to have JRE installed on machine. For this first we need to check weather JRE installed or not, if not installed then it needs to be installed. What approach needs to be followed?
I have tried with the below of code.
$LASTEXITCODE = 0
$workdir = "C:\Program Files (x86)\Java"
If (!(Test-Path $workdir))
{
$LASTEXITCODE = (Start-Process "D:\jre-6u26-windows-i586.exe" -ArgumentList "/s" -Wait -PassThru).Exitcode
}
If($LASTEXITCODE -eq 0)
{
$DCBdir = "C:\Program Files (x86)\Compart"
If (!(Test-Path $DCBdir))
{
$Installer="D:\sw.exe"
$responsefile="D:\Sresponse.varfile"
$a=#("-q", "-varfile", "$responsefile")
start-process $Installer -ArgumentList $a -wait
}
}
$chkdir = "C:\Program Files (x86)\SWFolder"
if(Test-Path -eq $chkdir)
{
[System.Windows.MessageBox]::Show('Installation completed successfully')
}
When I run script its workingfine as it is checking the previous installation and performing installation if not found the installation. But here I am getting as issue with this code.
If Java installed alredy means it should start the other installation. but here in my case its stopping the complete installation.
after installation completed, I need to display the message like " Installation completed". But here its not working. AnNy wrong in the above code..??

One package manager that I like to use is Chocolatey which has an approved package for JRE, it looks like. A quick check wmi will tell you whether or not java is installed:
$x = Get-WmiObject -Class Win32_Product -Filter "Name like 'Java(TM)%'" | Select -Expand Version
You could also use Test-Path pointed at registry keys you know exist for the package. Once you verify that JRE is not on the machine, then you can call out to Chocolatey to install it.

Related

PowerShell script for software installation using chocolatey

enter code here
# Step 1) install Chocolatey when needed
if (-not (Test-Path -Path "$env:ProgramData\Chocolatey\choco.exe" -PathType Leaf)) {
# from https://chocolatey.org/install
Set-ExecutionPolicy Bypass -Scope Process -Force
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
}
# Step 2) define the array of packages you are offering
$Packages = 'googlechrome','firefox','codeblocks','windbg','nasm',
'explorersuite','pestudio','vscode','sysinternals','python'
# Step 3) define the Show-Menu function
function Show-Menu {
Clear-Host
Write-Host "**********************************************"
Write-Host "LIST OF SOFTWARES"
# write the options using the array of packages
for ($i = 0; $i -lt $Packages.Count; $i++) {
# {0,2} means right align with spaces to max 2 characters
Write-Host ('{0,2}. {1}' -f ($i + 1), $Packages[$i])
}
Write-Host " q. Exit the script"
Write-Host "*************************************************"
Write-Host
}
# Step 4) enter an endless loop you only exit if the user enters 'q'
while ($true) {
Show-Menu
$UserInput = Read-Host "Enter the software number to be installed"
# test if the user wants to quit and if so, break the loop
if ($UserInput -eq 'q') { break }
# test if the user entered a number between 1 and the total number of packages (inclusive)
if ([int]::TryParse($UserInput,[ref]$null) -and 1..$Packages.Count -contains [int]$UserInput) {
# here you install the chosen package using the array index number (= user input number minus 1)
$packageIndex = [int]$UserInput - 1
Write-Host "Installing $($Packages[$packageIndex])"
choco install $Packages[$packageIndex] -y
}
else {
$availableOptions = 1..$Packages.Count -join ','
Write-Host "Error in selection, choose $availableOptions or q" -ForegroundColor Red
}
$null = Read-Host "Press Enter to continue"
}
Problem Statement:
I am writing power shell script using chocolatey for software downloading and installing automatically. My script will display a menu with the list of software's whenever users enter the number the corresponding software will download and install.
When i run the script the executable files are not showing in control panel and desktop icon is also not creating but i am getting the message in power-shell terminal that the software is installed but i am not able to see that application.
I need to put some conditions in my script they are:
If the software is already installed then the software should not be downloaded
When the software is installed it has to shown in control panel and desktop icon should be created.
If any upgrade is their like for googlechrome and firefox generally up gradation takes place then the script has to upgrade.
Please help me and edit my script if anything is wrong
Thanks in advance
Referencing this answer, check to see if the relevant software is installed by checking the following registry keys:
$InstalledSoftware = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*
$InstalledSoftware += Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*
If it's installed, you can either skip the installation altogether, or...
You can get the package managed under Chocolatey by "installing" the package anyways, but provide the -n (--skippowershell) parameter:
choco install -n packageName
This will download the package metadata but skip the actual PowerShell code (chocolateyInstall.ps1, which is embedded into all Chocolatey packages). This is the piece which runs MSIEXEC, an EXE installer, extracts zip archives for packages without a proper installer, etc. This has the benefit of allowing future updates to be manageable by Chocolatey without reinstalling the software which already exists.
Note: There may be some nuance surrounding specific packages you'll have to figure out, but for the majority of what is available as a Chocolatey package this approach will work.

TASK Names for Visual Studio Code for Windows System Installer script in Powershell

Looking for some help on writing a PowerShell script to install Visual Studio Code.
I have downloaded the Windows 64 System installer: VSCodeSetup-x64-1.56.2
My script so far:
$fullPath = <<Installer location>>
$vscApp = "VSCodeSetup-x64-1.56.2"
$appPath = join-path $fullPath $vscApp
Write-Host "App Path" $appPath
$arguments = '/SILENT /ALLUSERS /mergetasks="!runcode,????, ????, ???? ,????"'
Start-Process $appPath $arguments -Verb RunAs -Wait
I need the list of internal names for all of the check box items on the "Select Additional Tasks"
Select Additional Tasks GUI Screenshot
I want to turn on all four other tasks, both Add Open, Register code, and Add to Path. Only 1 of which seems to be default. While I do not need the desktop icon, from the Inno Setup docs, https://jrsoftware.org/ishelp/index.php?topic=setupcmdline, I can see the desktop Icon name is desktopicon. How and where would I find this list?
Thanks for any and all help!
Continuing from my comment.
There are several pre-built scripts, in several GitHub Repos for silent installs:
Example:
#Install-VSCode
# Download URL, you may need to update this if it changes
$downloadUrl = "https://go.microsoft.com/fwlink/?LinkID=623230"
# What to name the file and where to put it
$installerFile = "vscode-install.exe"
$installerPath = (Join-Path $env:TEMP $installerFile)
# Install Options
# Reference:
# http://stackoverflow.com/questions/42582230/how-to-install-visual-studio-code-silently-without-auto-open-when-installation
# http://www.jrsoftware.org/ishelp/
# I'm using /silent, use /verysilent for no UI
# Install with the context menu, file association, and add to path options (and don't run code after install:
$installerArguments = "/silent /mergetasks='!runcode,addcontextmenufiles,addcontextmenufolders,associatewithfiles,addtopath'"
#Install with default options, and don't run code after install.
#$installerArguments = "/silent /mergetasks='!runcode'"
Write-Verbose "Downloading $installerFile..."
Invoke-Webrequest $downloadUrl -UseBasicParsing -OutFile $installerPath
Write-Verbose "Installing $installerPath..."
Start-Process $installerPath -ArgumentList $installerArguments -Wait
Write-Verbose "Cleanup the downloaded file."
Remove-Item $installerPath -Force
You can also automate installing VSCode extensions.
Example:
Visual Studio Code: Getting Started with PowerShell
https://social.technet.microsoft.com/wiki/contents/articles/35780.visual-studio-code-getting-started-with-powershell.aspx
code --install-extension ms-vscode.powershell

Automating WSUS updates with PowerShell/PowerCLI

I'm looking to automate the process of installing WSUS updates on my VMs. To give a short overview, here are the things I want to accomplish (please let me know if my methods are moronic, I'd love to learn the right way for all of this.):
Check if the particular VM has any WSUS updates to install
If there are updates available, take a snapshot of the VM
Begin the WSUS install
Reboot the system, if necessary
I am currently able to check if the particular VM has updates and take a snapshot. Now I know I could just have this portion of the script run and configure a GPO to accomplish the rest of the tasks, but my thought process is that if I can do it all in the script, I will be able to check that the snapshot of the VM exists prior to installing the update. Below you can see what my script does as of now.
foreach ($vm in $vms) {
if ($vm.PowerState -eq "poweredOn") {
$output = Invoke-VMScript -ScriptText $script -VM $vm -GuestCredential $guestCred
if ($output.ScriptOutput -Notlike '0*') {
New-Snapshot -VM $vm -Name BeforeWSUS
}
}
}
After this I would like to perform a check to see if the snapshot exists for a vm, then install the WSUS update. If a reboot is necessary, then reboot.
Is there a way to do this? A better way to do this? Would really appreciate some insight, I'm new to Powershell.
Edit: I've checked on the PSWindowsUpdate Module, would that need to be on each VM I plan to update?
Yes, you would need PSWindowsUpdate installed on each VM.
You could include something like this in your script to check if PSWindowsUpdate is installed and if not, install it.
Set-PSRepository -Name "PSGallery" -InstallationPolicy Trusted
$Modules = "PSWindowsUpdate"
$Modules | ForEach-Object {
If (!(Get-Module -ListAvailable -Name $_)) {
Install-Module $_ -Verbose -Confirm:$false
}
}
I think that Install-Module requires PowerShell version 5.0.
Then you would use Get-WUInstall to install updates from your WSUS server. (It looks like it defaults to WSUS if configured via GPO.)
Probably throw in a -Confirm:$False to avoid it prompting you to allow each update.
More info on PSWindowsUpdate: https://github.com/joeypiccola/PSWindowsUpdate

PowerShell Script/Refresh

I have a script that installs software and logs what is happening. At the end of the install I use a command to check if the software is installed via the registry. Here is part of the script:
#Install Adobre Reader
Write-Verbose "$(Get-Date): Installing Adobe Reader"
$AdobeInstaller = "\\server\AcroRead.msi"
$AdobeArgs = 'TRANSFORMS="\\server\AcroRead.mst" /qn /norestart'
Start-Process $AdobeInstaller $AdobeArgs -Wait
#Check Adobe Reader Install
$InstalledProgs2 = Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* |
Select-Object DisplayName
$CheckProg2 = $InstalledProgs -like "*Adobe Acrobat Reader DC*"
if ( $CheckProg2 ) {
Write-Verbose "$(Get-Date): Adober Reader install finished successfully"
} else {
Write-Verbose "$(Get-Date): Adobe Reader install failed"
}
The script waits for the installer to finish, as it should, but then always reports as "Adobe Reader install failed" even though it is installed. If I run "check" part of the script after the initial script has finished it works as it should. It appears to me that PowerShell caches the current registry at the start of PowerShell and does not see the new install. Is there a command to refresh this or am I thinking incorrectly?

Active Directory Module

I have written a PowerShell script, an application that allow PC Refresh to set Company, DepartmentNumber, etc. on an AD object. In development everthing works fine. Obviously I have AD installed on my machine. I have compiled my app to a .exe and placed it on a network share where the techs will execute it from there as they start up a new computer or refresh from Windows 7 to Windows 10 mostly.
The problem is the new PC will not have Active Directory installed at this point in time. I need to find a way to have my app intall, import and run Active Directory as on start up of new or refreshed computers. How do I accomplish this?
Below is some relevant code I use to import the module if it exist on the machine.
$RestoreForm_Load = {
# Load the ActiveDirectory module if it's available
# Check if the ActiveDirectory module is installed
if ((Get-Module -ListAvailable | where { $_.Name -eq 'ActiveDirectory' }) -eq $null) {
$labelDialogRedRestore.Text += "You need to install the ActiveDirectory module!`n"
} else {
# Check if the ActiveDirectory module is allready Imported
if ((Get-Module ActiveDirectory) -eq $null) {
Import-Module ActiveDirectory -ErrorAction 'SilentlyContinue'
$labelDialogGreenRestore.Text += "ActiveDirectory module imported`n"
} else {
$labelDialogGreenRestore.Text += "ActiveDirectory allready imported`n"
}
}
Only the Windows Server versions have the AD module, or any other part of the RSAT (Remote Server Administration Tools) for that matter, available for installation out of the box. You can use Add-WindowsFeature (or Install-WindowsFeature, which replaced the former in Windows 2012 and newer) to install the module on a server:
Import-Module ServerManager
$os = (Get-WmiObject Win32_OperatingSystem).Caption
switch -wildcard ($os) {
'Windwos Server 2008*' {
Add-WindowsFeature RSAT-AD-PowerShell -IncludeAllSubFeatures
}
'Windows Server 2012*' {
Install-WindowsFeature RSAT-AD-PowerShell -IncludeAllSubFeatures
}
}
Windows client versions don't come with the RSAT. You need to install the correct RSAT package first before you can install the AD PowerShell cmdlets. The link list in the KB article is a little outdated, though. The link for the Windows 10 Preview RSAT package doesn't work anymore. Here is the download link for the release version.
Once you have installed the update on the clients, you can install the module for instance via dism:
dism /Online /Enable-Feature /FeatureName:RemoteServerAdministrationTools-Roles-AD-Powershell
Note that (at least on the client versions) the feature name may differ between versions (the feature is named RemoteServerAdministrationTools-Roles-AD-Powershell in the Windows 7 RSAT, but RSATClient-Roles-AD-Powershell in the Windows 10 RSAT), so you may need to use a switch statement on the clients as well:
$os = (Get-WmiObject Win32_OperatingSystem).Caption
$name = switch -wildcard ($os) {
'Windows 7*' { 'RemoteServerAdministrationTools-Roles-AD-Powershell' }
'Windows 8*' { '???' }
'Windows 10*' { 'RSATClient-Roles-AD-Powershell' }
}
& dism /Online /Enable-Feature /FeatureName:$name
Also, beware that regardless of which system you're installing the module on (server or client) you must have .NET framework 3.5.1 or 4.5 installed, otherwise the module won't work (if you can even install it in the first place).
You could install the module in your script with the following command:
Add-WindowsFeature RSAT-AD-PowerShell
Note that this feature requires the .NET Framework 3.5.1 feature too which can be installed with the following command:
Add-WindowsFeature net-framework-core
While you can install Active Directory on these machines just to run your code, I'd suggest setting up a session to a computer that already has it installed instead. If the Techs are hands on and have credentials to access AD then this will work better.
$Session = New-PSSession -ComputerName DC -Credential (Get-Credential) -Name AD
Enter-PSSession -Session $Session
Import-Module ActiveDirectory
Doing-AD -Stuff
...
Disconnect-PSSession
With this approach, the Tech will be prompted for their credentials, the script will run your AD stuff, and the client machine won't have RSAT tools enabled or installed.