Run powershell Commands in Dockerfile - windows

I have a PowerShell script and I tried running in the Docker using the RUN command in the windows base OS image but was unable due to permission issues. SO I thought to give the PS script in the Dockerfile itself but getting errors
I am using the "mcr.microsoft.com/windows:1909" image and I am attaching my PowerShell script below
param(
[Parameter()]
[ValidateNotNull()]
[string[]]$AdditionalExtensions = #(),
[switch]$LaunchWhenDone
)
if (!($IsLinux -or $IsOSX)) {
$codeCmdPath = "C:\Program Files (x86)\Microsoft VS Code\bin\code.cmd"
try {
$ProgressPreference = 'SilentlyContinue'
if (!(Test-Path $codeCmdPath)) {
Write-Host "`nDownloading latest stable Visual Studio Code..." -ForegroundColor Yellow
Remove-Item -Force $env:TEMP\vscode-stable.exe -ErrorAction SilentlyContinue
Invoke-WebRequest -Uri https://vscode-update.azurewebsites.net/latest/win32/stable -OutFile $env:TEMP\vscode-stable.exe
Write-Host "`nInstalling Visual Studio Code..." -ForegroundColor Yellow
Start-Process -Wait $env:TEMP\vscode-stable.exe -ArgumentList /silent, /mergetasks=!runcode
}
else {
Write-Host "`nVisual Studio Code is already installed." -ForegroundColor Yellow
}
$extensions = #("ms-vscode.PowerShell") + $AdditionalExtensions
foreach ($extension in $extensions) {
Write-Host "`nInstalling extension $extension..." -ForegroundColor Yellow
& $codeCmdPath --install-extension $extension
}
if ($LaunchWhenDone) {
Write-Host "`nInstallation complete, starting Visual Studio Code...`n`n" -ForegroundColor Green
& $codeCmdPath
}
else {
Write-Host "`nInstallation complete!`n`n" -ForegroundColor Green
}
}
finally {
$ProgressPreference = 'Continue'
}
}
else {
Write-Error "This script is currently only supported on the Windows operating system."
}```

Related

How to immoderately return on build error by Power Shell visual studio build script

I have following script for building several projects one by one. But this scripts keeps running even if there is an error. I would like to immediately stop the script and notify the ures that there is a compiler error for one of the project failed to build. Even if possible to notify exactly what is failed to compile. Please suggest me how to do it?
param (
[parameter(Mandatory=$false)]
[String]$build
)
function buildSas
{
param
(
[parameter(Mandatory=$true)]
[String] $path,
[parameter(Mandatory=$false)]
[bool] $clean = $false
)
process
{
$msBuildExe = 'C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\MSBuild.exe';
if(-not (Test-Path $msBuildExe))
{
Write-Host "MSBuild 15 is not installed, please install MSBuild 15 to use this build script." -ForegroundColor Red -BackgroundColor Yellow
exit;
}
if ($clean) {
Write-Host "Cleaning $($path)" -foregroundcolor green
& "$($msBuildExe)" "$($path)" /t:Clean /m:4
}
Write-Host "Building $($path)" -foregroundcolor green
& "$($msBuildExe)" "$($path)" /t:Rebuild /m:4 /p:BuildInParallel=true
}
}
function buildVs
{
Write-Host "Building all visual studio projects only." -ForegroundColor Magenta -BackgroundColor White;
buildSas .\proj1.sln
buildSas .\proj2.sln
buildSas .\proj3.sln
buildSas .\proj4.sln
# many project in list
Write-Host "visual studio projects build done." -ForegroundColor Magenta -BackgroundColor White;
}
if($build -eq "vs")
{
buildVs;
return;
}
buildVs
if msbuild.exe returns different exit codes I'd add function to start msbuild using Start-Process. Something like:
$SuccessReturnCode=#(0,3010)
$ProcesTimeOut=3000
$buildparam="$($path) /t:Rebuild /m:4 /p:BuildInParallel=true"
Write-Log -message "Invoking: $myProcess $myArgs, process time-out:$ProcTimeOut seconds"
$process = (Start-Process -FilePath $msBuildExe -windowstyle Hidden -ArgumentList $buildparam -PassThru)
Try {
$process | Wait-Process -Timeout $ProcTimeOut -ErrorAction Stop
Write-Log -message "Completed with return code: $($process.ExitCode)"
if ($SuccessReturnCode -notcontains $process.ExitCode) {
Write-Log -level 'error' -message 'something went wrong'
exit 255
}
}
Catch {
$ErrorMessage = $_.Exception.Message
Write-Log -level 'error' -message "The error message was: <$($ErrorMessage)>"
$pwid=$process.Id.ToString()
taskkill.exe /PID $pwid /T /F
}

Powershell Script to deploy multiple software using variables

I am building a deployment script to install software on a new device using a ppkg file.
The script looks at which drive is the USB drive and copies the software over to the local temp folder and runs them according to a set of variables as shown below.
What I am struggling to do is simplify the script so I am not repeating code 7 times down the page, I want to just run a loop 7 times to pull in the needed software. I tried an array but I think I am not quite understanding it completely.
This is my script so far with the repeating code:
#SOE application Variables
#applcation1 CM_client
$app1name = "Config Manager Client 1706"
$app1skip = "no"
$app1path = "$env:SystemDrive\temp\soe\application_installs\app1\CM_client_inst_1706\"
$app1runcommand = "clientx64.bat"
$app1arguments = ""
#applcation2
$app2name = "Office 2016 Pro Plus"
$app2skip = "no"
$app2path = "$env:SystemDrive\temp\soe\application_installs\app2\O2016\"
$app2runcommand = "setup.exe"
$app2arguments = "/configure configuration.xml"
#log Folder
$datetime = Get-Date -format "yyyy.MM.dd-HH.mm.ss"
$logpath = "$env:ALLUSERSPROFILE\SOEInst_ppkg\$datetime"
New-Item -Path $logpath -ItemType Directory -ErrorAction SilentlyContinue
#Transcript Start
Start-Transcript -Path $logpath\SOE-app-installer-ppkg-$datetime.log
#Timer Function
$pkgremovetime = Get-Date -format "HH:mm:ss"
write-host "Script Start Time - $pkgremovetime"
#Find USB Drive
Write-host Discovering USB Drive
$drives = (GET-WMIOBJECT –query “SELECT * from win32_logicaldisk").DeviceID
foreach ($drive in $drives) {
$usbdrive = (dir $drive USBIMG.FILE | Select-Object -Unique "USBIMG.FILE")
if ($usbdrive -match "USBIMG.FILE*") {
$datadrive = $drive
}
}
Write-host Found $datadrive is the USB drive
#Copy Applications to Local Drive
Write-Host Creating Installer Folder
New-Item -Path $env:SystemDrive\temp\SOE -ItemType Directory
Copy-Item $datadrive\application_installs $env:SystemDrive\temp\soe -Recurse -Verbose
#Install Applications
#Application 1
if ($app1skip -eq "no") {
if ($app1arguments) { #Arguments Variable Populated
Write-Host Installing Applcation 1 `($app1name`)
$app1 = Start-Process -Wait -FilePath $app1path$app1runcommand -ErrorAction Continue -ArgumentList $app1arguments -WindowStyle Normal
if ($app1.ExitCode -eq "0") {
Write-Host $app1name Installed ok
} Else {
Write-host $app1name install exited with code $app1.ExitCode
}
}
}Else { #Argurments Variable Empty
Write-Host Installing Applcation 1 `($app1name`)
$app1 = Start-Process -Wait -FilePath $app1path$app1runcommand -ErrorAction Continue -WindowStyle Normal
if ($app1.ExitCode -eq "0") {
Write-Host $app1name Installed ok
} Else {
Write-host $app1name install exited with code $app1.ExitCode
}
}
#Application 2
if ($app2skip -eq "no") {
if ($app2arguments) { #Arguments Variable Populated
Write-Host Installing Applcation 2 `($app2name`)
$app2 = Start-Process -Wait -FilePath $app2path$app2runcommand -ErrorAction Continue -ArgumentList $app2arguments -WindowStyle Normal
if ($app2.ExitCode -eq "0") {
Write-Host $app2name Installed ok
} Else {
Write-host $app2name install exited with code $app2.ExitCode
}
}
}Else { #Argurments Variable Empty
Write-Host Installing Applcation 2 `($app2name`)
$app2 = Start-Process -Wait -FilePath $app2path$app2runcommand -ErrorAction Continue -WindowStyle Normal
if ($app2.ExitCode -eq "0") {
Write-Host $app2name Installed ok
} Else {
Write-host $app2name install exited with code $app2.ExitCode
}
}
#cleanup
Remove-Item $env:SystemDrive\temp\soe -Recurse -Force -Verbose
#get end time
$pkgremovetime_end = Get-Date -format "HH:mm:ss"
#calculate time difference
$timetaken = New-TimeSpan $pkgremovetime $pkgremovetime_end
if ($timetaken.Seconds -lt 0) {
$Hrs = ($timetaken.Hours) + 23
$Mins = ($timetaken.Minutes) + 59
$Secs = ($timetaken.Seconds) + 59 }
else {
$Hrs = $timetaken.Hours
$Mins = $timetaken.Minutes
$Secs = $timetaken.Seconds }
$Difference = '{0:00}:{1:00}:{2:00}' -f $Hrs,$Mins,$Secs
#log time difference
write-host "Script End Time - $pkgremovetime_end"
Write-Host "Total time taken $difference"
#Transcript End
Stop-Transcript
I suggest you make a function which takes in the variables. I did a quick comparison of your installation codes and something like this should work
function installApplication{
Param($skip, $arguments, $name, $path, $runcommand)
if ($skip -eq "no"){
if ($arguments){
write-host "Installing Application $appname"
$app = Start-Process -Wait -FilePath $path$runcommand -ErrorAction....
if($app.ExitCode -eq "0"){
....
....
}
and so on, You can then call the function using
installApplication $app1skip $app1arguments $app1name $app1path $app1runcommand
installApplication $app2skip $app2arguments $app2name $app2path $app1runcommand
Your input arguments will replace the function parameters in the order you pass them in, or you can use -skip $app1skip to assign the parameters.
If your repeating the same code too many times, I suggest throwing it into something like diffchecker, put the code into a function and replace all the differences with variables.
You can see your code here https://www.diffchecker.com/FxAIdD6g (1 Day only)

Check server before starting service

I need to edit a script. There is a service that is on two Windows Server 2008 R2. They are load balanced. I need it so when I run the script that starts the service on the primary server and the secondary, so before it even start the service on both servers, the goes out and checks to ensure the primary server is up and running, then continues on as normal to start the services on both servers.
# Start Appian
function StartAppian {
$APNSVC = Get-Service -Name $AppianService
if (!$APNSVC) {
Write-Host "Appian Service does not exist"
return
}
# Check to see if Appian's service is already started
if ($APNSVC.Status -eq "Running") {
if ($LB) {
if ($MULEAPNSVC.Status -eq "Running") {
Write-Host "Appian Service on the Load Balanced Server already is started!" -ForegroundColor Yellow
return
}
}
Write-Host "Appian Service already is started!" -ForegroundColor Yellow
Read-Host "Press any key to return"
return
}
# Check if DEV's Process Design has a writing_*.kdb file and delete it
if ($Server -eq "DEV") {
#gw1
if (Test-Path $APPIAN_HOME\server\process\design\gw1\writing_*.kdb) {
Write-Host "Removing writing_*.kdb from GW1" -ForegroundColor Yellow
Remove-Item $APPIAN_HOME\server\process\design\gw1\writing_*.kdb
}
#gw2
if (Test-Path $APPIAN_HOME\server\process\design\gw2\writing_*.kdb) {
Write-Host "Removing writing_*.kdb from GW2" -ForegroundColor Yellow
Remove-Item $APPIAN_HOME\server\process\design\gw2\writing_*.kdb
}
}
Write-Host "Starting Appian"
# Place the name of the service here to start for Appian
Start-Service $AppianService
Notify("StartAppian")
if ($LB) {
(Get-Service $MULEAPNSVC.Name -ComputerName $MULE).Start()
Write-Host "Starting Mule's Appian" -ForegroundColor Magenta
}
cmd.exe "/C $APPIAN_HOME\server\_scripts\diagnostic\checkengine.bat -s > $logdir\Startup.log"
# These lines check the Startup log for fatals and errors at the beginning
$fatals = Select-String FATAL $logdir\Startup.log
$errs = Select-String ERROR $logdir\Startup.log
# Check for errors and fatals again
$fatals = Select-String FATAL $logdir\Startup.log
$errs = Select-String ERROR $logdir\Startup.log
Write-Host "Still warnings or Errors in CE" -ForegroundColor Yellow
# Increment times
$times = $times + 1
# If times > threshold, email out error message
if ($times -gt $threshold) {
SendAlert("There is a problem with Appian - It won't start")
Write-Host "There was a problem with Appian..it took too long to start - emailing alert" -ForegroundColor Red
Read-Host "Press any key to exit"
}
}
Write-Host "Appian Started" -ForegroundColor Green
Read-Host "Press any key to return"
}
You can do that with a simple Test-Connection at the start of the script.
if ($ping = Test-Connection -ComputerName PrimaryServerName -Quiet) {
Write-Host "Host avalible"
}
else {
Write-Host "Host unavalible"
Exit
}
any other suggestions?
if (Test-Connection ServerName -Count 1 -Quiet) {
Write-Host "Host avalible"
}
else {
Write-Host "Host unavalible"
Exit
}
this doesnt work. I want it to test the if the server is up or not, if its not, exit the script, if it is, continue on with the script. When testing this on ISE it work, but when i launch the script it doesn't

Powershell GPO start up script - Uninstall Microsoft Updates

I can run this script manually/interactively with an account that has local admin rights and it works perfectly fine, but when I insert it into a GPO start up script or deploy it through SCCM, nothing happens. It just opens the console window and then closes it - the MS Updates remain installed.
$PatchList = #("KB2553154","KB2899519","KB2910902","KB3008923","KB3012176","KB3013126")
function Remove-Update
{
$HotFixes = Get-HotFix
foreach ($HotFix in $HotFixes)
{
foreach ($KBID in $PatchList)
{
if ($KBID -eq $HotFix.HotfixId)
{
"Inside first if"
$KBID = $HotFix.HotfixId.Replace("KB", "")
$RemovalCommand = "wusa.exe /uninstall /kb:$KBID /quiet /norestart"
Write-Host "Removing $KBID from the target."
Invoke-Expression $RemovalCommand
break
}
if ($KBID -match "All")
{
$KBNumber = $HotFix.HotfixId.Replace("KB", "")
$RemovalCommand = "wusa.exe /uninstall /kb:$KBNumber /quiet /norestart"
Write-Host "Removing update $KBNumber from the target."
Invoke-Expression $RemovalCommand
}
if ($KBID -match "Security")
{
if ($HotFix.Description -match "Security")
{
$KBSecurity = $HotFix.HotfixId.Replace("KB", "")
$RemovalCommand = "wusa.exe /uninstall /kb:$KBSecurity /quiet /norestart"
Write-Host "Removing Security Update $KBSecurity from the target."
Invoke-Expression $RemovalCommand
}
}
while (#(Get-Process wusa -ErrorAction SilentlyContinue).Count -ne 0)
{
Start-Sleep 3
Write-Host "Waiting for update removal to finish ..."
}
}
}
}
Remove-Update
I know that with a GPO start up script or SCCM deployment, the account being used to run the script is the system account. Not sure if that is causing the issue?
Any advice would be greatly appreciated.

How can I set up continuous deployment for a SharePoint 2010 Visual Studio solution?

I want to automatically build .wsp packages and re-deploy them on a staging server after each commit. I know how to setup CruiseControl.Net for continuous integration, but I don't know how to build and deploy the packages. So far I got MSBuild to generate .wsp files , but I am struggling with a automatic re-deployment script. What I got so far is a PowerShell script:
param([string]$siteUrl = "http://machine.local")
$ErrorActionPreference = "Stop"
function WaitForPendingJob
{param ($sol)
$counter = 1
$sleeptime = 2
$safeguard = 100
while( $sol.JobExists -and ( $counter -lt $safeguard ) ) {
Write-Host -f yellow -NoNewLine "."
sleep $sleeptime
$counter++
}
Write-Host ""
}
function InstallOrUpdateSolution
{param ($SolutionWsp, $SiteUrl, $featureGuid)
$FullPath = resolve-path $SolutionWsp
$farm = Get-SPFarm
$sol = $farm.Solutions[$solutionWsp]
if ($sol)
{
Write-Host -f Green "Going to uninstall $SolutionWsp"
if( $sol.Deployed -eq $TRUE )
{
Write-Host -f Green "Deactivating feature $featureGuid at $SiteUrl"
Disable-SPFeature -Identity $featureGuid -Url $SiteUrl -Confirm:$false -force -ErrorAction Continue
Uninstall-SPSolution -Identity $SolutionWsp -WebApplication $SiteUrl -Confirm:$false -ErrorAction Continue
Write-Host -f yellow -NoNewLine "waiting for retraction"
WaitForPendingJob $sol
}
Write-Host -f Green "$SolutionWsp is retracted."
Write-Host -f Green "Going to Remove $SolutionWsp"
Remove-SPSolution -Identity $SolutionWsp -Force -Confirm:$false -ErrorAction Continue
Write-Host -f Green $SolutionWsp is deleted from this Farm
}
Add-SPSolution -LiteralPath $FullPath
Install-SPSolution -Identity $SolutionWsp -WebApplication $SiteUrl -GACDeployment -CASPolicies -Force
$sol = $farm.Solutions[$SolutionWsp]
if ($sol.Deployed -eq $false ) {
write-host -f yellow -NoNewLine "waiting for deployment"
WaitForPendingJob $sol
}
Write-Host -f Green $SolutionWsp deployed $sol.Deployed
Write-Host -f Green "Activating feature $SolutionWsp at $SiteUrl"
Enable-SPFeature -Identity $featureGuid -Url $SiteUrl
}
function RestartTimer
{
Write-Host -f Green Restarting OWSTIMER instances on Farm
$farm = Get-SPFarm
$farm.TimerService.Instances | foreach {$_.Stop();$_.Start();}
}
$date = Get-Date
Write-Host -f Green "Starting upgrade at " $date
Add-PsSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue
InstallOrUpdateSolution "Solution1.wsp" $siteUrl "2c6ffaf7-84df-465c-be55-8136926d3e02"
InstallOrUpdateSolution "Solution2.wsp" $siteUrl "0c6be7af-cccd-4ccd-9b61-deffd16f7830"
InstallOrUpdateSolution "Solution3.wsp" $siteUrl "8f4862d3-94ea-467b-bdeb-2352295e08c3"
RestartTimer
$date = Get-Date
Write-Host -f Green "Upgrade finished at" $date
This breaks with seemingly random errors, while the deployment from Visual Studio 2010 works every time. How can I deploy the .wsp's from command line in a fail-proof way like the Visual Studio does it?
Why don't you just use Update-SPSolution instead of retract-delete-install-deploy sequence?
First of all, why are you over-complicating the deployment process by using PowerShell instead of stsadm in a batch file? Is there a need for PowerShell?

Resources