TASK Names for Visual Studio Code for Windows System Installer script in Powershell - 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

Related

How do I add a powershell script to be run post setup during a windows 10 unattended install?

I may be going about this the wrong/more difficult way. I am open to suggestions.
I am running NTLite v2.3.8.8920 [HOME] ((c) NTlitesoft d.o.o) to create unattended Windows 10 discs. After years of doing unattended discs and realizing the ever expanding size of the disc, (Latest disc was 32.73GB!), I found WinGet, the absolutely amazing repository, and have even gone as far as to create my own installer!
The issue for today is: how do I access WinGet during an unattended installation? I have compiled a list of applications that I use frequently; most that I have been hard coding to the disc and thus this incredible size; and I would love to be able to run this script post-setup and save the time and space. Here is my code:
#The first batch here is a function I created for notification purposes. Not sure how to do timed popups in Powershell yet.
#Get Words
function GW($myinput){
$WS = New-Object -ComObject "Wscript.Shell"
$ws.popup($myinput,3,'TK Installer',64)|SET-CLIPBOARD}
SET-CLIPBOARD to offload the popup response code. Need to find a better output or a way to prevent printing this response.
function install-myapps(){
Clear-Host
#Variable to hold the application list
$myapps = (
'Microsoft.PowerShell',
'Microsoft-Windows.Terminal',
'Microsoft.DotNet.SDK.3_1',
'Microsoft.DotNet.SDK.5',
'Microsoft.DotNet.SDK.6',
'Microsoft.MSIXCore',
'Microsoft.msmpisdk',
'Microsoft.ADKPEAddon',
'Microsoft.WebDeploy',
'9N5LW3JBCXKF',
'Nlitesoft.NTLite',
'Libretro.RetroArch',
'Notepad++.Notepad++',
'CodecGuide.K-LiteCodecPack.Full',
'Foxit.FoxitReader',
'7zip.7zip',
'OBSProject.OBSStudio',
'XnSoft.XnConvert',
'XnView.Classic',
'XnSoft.XnViewMP',
'corel.winzip',
'XP8K0J757HHRDW')
#Parser
ForEach-Object($aa in $myapps.Split(',')){
#Notification
GW "Installing $aa`nPlease wait..."
#Installer
WinGet install $aa --silent --accept-package-agreements --accept-source-agreements --force}
}
This code works perfectly in both command line and exe format; the latter using PS2EXE or IExpress. I just cannot figure out how to instantiate it post-setup from the unattended Win1021H2 side. Any help or insight would be greatly appreciated!
I was unable to figure out the process for this so I worked it around differently.
Below is how I fixed this situation:
# The first section opens and names function and
# declares variable $Hopeful applied to the full URI for the application we are installing
# !Considering using get-input but for now we will just use a replaceable variable!
# The second section begins the downloading and saving process
# Begins by separating the application from the URI assuming the format is as www.domain.com/application.exe
# Note now that the variable $JustApp will pull the just the last portion of the URI which is the application name
# Also, we'll make sure that what we're trying to do is possible by checking the extension of the last object
# Because wget needs 2 things; the URI and a place for the download to go; I am creating a directory to put these
# downloads in. Thus, $MyDir\$JustApp is now the default file point.
cls
Clear-Host
$MyDir = "d:\TKDI\"
# Create directory
if($mydir|Test-Path){
"My Directory Already Exists!"
}else{
md $MyDir -Force
}
# Section 1
Function TKDI($Hopeful,$MyArgs){
$_|select
# Section 2
$JustApp = $hopeful -split('/')|select -last 1
if($justapp -match "exe")
{
switch($MyArgs)
{
inno{$x ='/sp- /silent /forcecloseapplications /restartapplications /norestart'}
S{$x ='/S'}
silent{$x ='/silent'}
quiet{$x ='/quiet'}
passive{$x ='-passive'}
default{$x =$myargs}
un{$x ='-uninstall'}
$null{$x='/?'}
}
cls
echo "Processing $justapp"
if(Test-Path $mydir$justapp -PathType Leaf){echo 'File Downloaded Already!'}else{wget -Uri $hopeful -OutFile $MyDir$justapp}
$noteit = 'Installing $justapp in 5 seconds...'
$x=6;while($x-- -ge 1){cls;Write-host $x;sleep 1}
start -verb runas -wait -FilePath $mydir$justapp -ArgumentList $x
}elseif($justapp -match "msi")
{
cls
echo "You're file will be downloaded and installed!"
wget -Uri $hopeful -OutFile $MyDir$justapp
start -wait -Verb runas msiexec.exe -ArgumentList "-i $mydir$justapp /passive /norestart"
}else{
echo "This URI does not result in an application!"
}
}
tkdi www.example.com/index.exe inno #Installs beautifully```

In PowerShell script, how can I restore packages to resolve error: This project references NuGet package(s) that are missing on this computer

I am tasked with writing a PowerShell script to download the latest source code for a given branch, rebuild it and deploy it. The script I've written, is able to download projects, and in most cases has been able to rebuild them. But with one web project I get this error:
error : This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is ..\packages\Microsoft.Net.Compilers.2.0.1\build\Microsoft.Net.Compilers.props.
I've researched if PowerShell has a Update-Package command like the one available in the VS command prompt but have been unable to find the equivalent.
I know there's a cmdlet for Packages but from what I've seen they're used to update a specific package...what I need is to be able to have it download/update all packages referenced in the project.
Some points that might be of interest...
When I get latest on the solution to a new empty folder, the only thing in the packages folder is Modernizr.2.6.2. This is the same whether I'm getting latest in VS or in my PowerShell script.
If I open the solution within VS 2017, I am able to rebuild the solution with no problems. It downloads/installs over a dozen other packages...one of which is the Microsoft.Net.Compilers.props package referred to in the error message.
But if I delete everything and re-download the source code and then through my PowerShell script I call MSBuild to rebuild the solution I get the error mentioned above. It never seems to download/install the missing packages.
Anyone have any ideas how I can use MSBuild within my PowerShell script to rebuild the project and have it automatically update/install any packages it needs?
Thanks
I was able to find a solution to my problem on this page :Quickly Restore NuGet Packages With PowerShell
On that page is a script that uses Nuget.exe to download the packages based on the packages.config:
#This will be the root folder of all your solutions - we will search all children of
this folder
$SOLUTIONROOT = "C:\Projects\"
#This is where your NuGet.exe is located
$NUGETLOCATION = "C:\Projects\NuGet\NuGet.exe"
Function RestoreAllPackages ($BaseDirectory)
{
Write-Host "Starting Package Restore - This may take a few minutes ..."
$PACKAGECONFIGS = Get-ChildItem -Recurse -Force $BaseDirectory -ErrorAction SilentlyContinue | Where-Object { ($_.PSIsContainer -eq $false) -and ( $_.Name -eq "packages.config")}
ForEach($PACKAGECONFIG in $PACKAGECONFIGS)
{
Write-Host $PACKAGECONFIG.FullName
$NugetRestore = $NUGETLOCATION + " install " + " '" + $PACKAGECONFIG.FullName + "' -OutputDirectory '" + $PACKAGECONFIG.Directory.parent.FullName + "\packages'"
Write-Host $NugetRestore
Invoke-Expression $NugetRestore
}
}
RestoreAllPackages $SOLUTIONROOT
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
I modified and added this function to my PS script and call it first to download all the packages and that does the job!
You need to call the restore target of MSBuild to download NuGet packages. You can do that by running something like:
git clone [your repo]
cd [your repo]
msbuild /target:Restore [Your Solution]
msbuild [Your Solution]
function buildVS
{
param
(
[parameter(Mandatory=$true)]
[String] $path,
[parameter(Mandatory=$false)]
[bool] $nuget = $true,
[parameter(Mandatory=$false)]
[bool] $clean = $true
)
process
{
$msBuildExe = 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Current\Bin\MSBuild.exe'
if ($nuget) {
Write-Host "Restoring NuGet packages" -foregroundcolor green
& "$($msBuildExe)" "$($path)" /p:Configuration=Release /p:platform=x64 /t:restore
}
if ($clean) {
Write-Host "Cleaning $($path)" -foregroundcolor green
& "$($msBuildExe)" "$($path)" /t:Clean /m
}
Write-Host "Building $($path)" -foregroundcolor green
& "$($msBuildExe)" "$($path)" /t:Build /p:Configuration=Release /p:platform=x64
}
}

Install software from a list using Powershell

I am building a script to automate computer build and configuration: The idea is that from WDS it comes as clean as possible, automatically runs this script which will check the serial number, query our Workday database of assets and configure the OS according to what the user assigned to that system needs.
Right now I am focusing on 3 big groups: Laptop, Desktop, and Lab. All 3 will have some SW that will be the same and some that will be specific for each. My issue is with msiexec: Initially, I hard-coded all the installations for each group. but this means that I will have to change the script each time something is updated (say a new app is rolled out as default). which is not ideal.
function Install-Desktop {
#Write-Output "Here will be the install Desktop computer script"
$IPATH="<Path To root sw folder>"
#Software List
<# SOFTWARE LIST #>
$office="$IPATH\script\o365"
$webex="$IPATH\script\webex"
$chrome="$IPATH\script\chrome"
#install Ofice:
Invoke-Expression "$office\setup.exe /configure $office\O365.xml"
$params = '/i', "$webex\webexapp.msi",'/qb!','/norestart'
Start-Process msiexec -ArgumentList "$params" -Wait -PassThru
$params = '/i', "$chrome\GoogleChromeStandaloneEnterprise64.msi",'/qb!','/norestart'
Start-Process msiexec -ArgumentList $params -Wait -PassThru
}
This piece of code works well.
Now my idea was to import from a list the software to be installed (it is easier to maintain a list than to modify the script every time). something like:
function install-software {
param (
[String]$Type
)
$IPATH=<ROOT SW Folder>
$SoftWares=Import-Csv -Path "$IPath\script\$Type`.csv" #there will be a Laptop.csv in that path
foreach ($Software in $SoftWares) {
#detect if it is msiexect or other:
# (this has to do with how the csv is built, the first parameter is '/i' if it is an msi installer)
if ($Software.param1 -eq "'/i'") {
Start-Process msiexec -ArgumentList $Software -Wait -PassThru
}
else {
$Params=[string]::Join(" ",$Software.param1,$Software.param2,$Software.param3,$Software.param4)
Invoke-Expression "$Params"
}
}
}
This only works on the else part. However on the msiexec side of the if, the MSI opens as without arguments. I tried a lot of ways to pass the args, none worked. I am not a PowerShell guru in any way, so there is probably something that I am missing to see here.
Well, it looks like you have to pass the full path, it doesn't even let you use mounted net drive: so the answer was on the csv. instead of S:\<path to installer> it had to be \<Full path to installer> and i had to get rid of all the quotes and double quotes as well.

silent installation using 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.

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?