Change what user code deploy executes scripts under windows - powershell

I have a code deploy project with an app spec.yml file. It has a list of hooks that call powershell scripts.
The code deploy has scripts within that is moved onto the ec2 machine. I’m then trying to use scripts within my app spec to call the scripts copied to the deploy folder
version: 0.0
os: windows
files:
- source: /deploy
destination: /things
hooks:
AfterInstall:
- location: ./install.ps1
timeout: 300
These powershell scripts call other batch files to setup services
# Fail on all errors
$ErrorActionPreference = 'Stop'
# Are you running in 32-bit mode?
# (\SysWOW64\ = 32-bit mode)
if ($PSHOME -like "*SysWOW64*")
{
Write-Warning "Restarting this script under 64-bit Windows PowerShell."
# Restart this script under 64-bit Windows PowerShell.
# (\SysNative\ redirects to \System32\ for 64-bit mode)
& (Join-Path ($PSHOME -replace "SysWOW64", "SysNative") powershell.exe) -File `
(Join-Path $PSScriptRoot $MyInvocation.MyCommand) #args
# Exit 32-bit script.
Exit $LastExitCode
}
D:
cd d:/install/scripts
Call installservices.bat
And then the batch script looks like this..which installs a windows service
App.exe /install
App2.exe/install
The issue I am running into is when the code deploy executes these powershell scripts it’s from a specific “environment” for code deploy but not as a user on windows.
It executes under this directory C:\Windows\system32
So the installer that is called automatically is not able to find a user data folder on the current executing user to drop config files to complete the install.
If I manually run the powershell script from the directory it works fine as I’m logged in as user, its in the context of code deploy executing the script that it no longer works
Is there a way to execute power shell scripts outside of how code deploy executes it, or execute as a specific user on windows?
I see Linux has a run as option for their app spec, but that option is not for windows.
This is on a windows Ec2 machine

Related

How to troubleshoot the error [The term 'pwsh.exe' is not recognized as the name of a cmdlet, function, script file, or operable program]?

While creating a new pipeline on Azure DevOps to set up a CI for a .NET project, I set up the following PowerShell script to automate the .NET Core setup.
Here is the script:
$ErrorActionPreference="Stop"
$ProgressPreference="SilentlyContinue"
# $LocalDotnet is the path to the locally-installed SDK to ensure the
# correct version of the tools are executed.
$LocalDotnet=""
# $InstallDir and $CliVersion variables can come from options to the
# script.
$InstallDir = "./cli-tools"
$CliVersion = "1.0.1"
# Test the path provided by $InstallDir to confirm it exists. If it
# does, it's removed. This is not strictly required, but it's a
# good way to reset the environment.
if (Test-Path $InstallDir)
{
rm -Recurse $InstallDir
}
New-Item -Type "directory" -Path $InstallDir
Write-Host "Downloading the CLI installer..."
# Use the Invoke-WebRequest PowerShell cmdlet to obtain the
# installation script and save it into the installation directory.
Invoke-WebRequest `
-Uri "https://dot.net/v1/dotnet-install.ps1" `
-OutFile "$InstallDir/dotnet-install.ps1"
Write-Host "Installing the CLI requested version ($CliVersion) ..."
# Install the SDK of the version specified in $CliVersion into the
# specified location ($InstallDir).
& $InstallDir/dotnet-install.ps1 -Version $CliVersion `
-InstallDir $InstallDir
Write-Host "Downloading and installation of the SDK is complete."
# $LocalDotnet holds the path to dotnet.exe for future use by the
# script.
$LocalDotnet = "$InstallDir/dotnet"
When I try to run the build, I have got the following error:
and
I've already searched on Google for people who have the same problem and how to fix it. But I haven't found much information yet. The Azure DevOps forum doesn't help either.
As mentioned in the comment from above, all you have to do is install the appropriate version of PowerShell on the machine that Agent is running on. For example, PowerShell 7. Then you have to make sure that the environment variable path is set. This variable should point to the directory with PowerShell Core.
Windows
Just install PowerShell Core with the Windows Installer (.msi file from PowerShell Git repository). In this case, the path environment variable is automatically set or expanded so that there will be the path to the directory with pwsh.exe under this variable.
Linux
Install PowerShell Core that is supported by your distribution. Make sure that there is a path variable in your ~/.bashrc file and that path contains the path to the directory with PowerShell Core.
Note: If Azure Agent is already running, you have to restart it so that it sees the changes in the path variable. Hence, on Windows, just restart the agent if run interactively and restart the service if run as a service. On Linux, you can follow this guide in order to update the environment variables that were passed to the Agent.
I know you have already configured your script as a PowerShell Core script, but for completeness I add this: If you use a PowerShell task in your Azure pipeline, the Core version of PowerShell is not set for it by default. In order to run the task as the PowerShell Core script, add this to the YAML code of the task: pwsh: true. Otherwise, if you are still using the old graphical interface, check the "Use PowerShell Core" checkbox under the "Advanced" heading for the task.

Powershell not finding PNPUTIL when script launched from shortcut

I have a Powershell script to install TCP/IP printers on Windows 10 that uses PNPUTIL to load drivers. When the script is run from a Powershell window, everything works great.
When I launch the script from a shortcut using the format
C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -file MyScript.PS1
I get an error 'The term 'pnputil.exe' is not recognized as the name of a cmdlet, function, script file, or operable program' when PNPUTIL is called. The rest of the script runs fine.
Relevant code:
Write-Host `n 'Installing printer driver..'
pnputil.exe /add-driver "\\myServer\HP UPD PCL 5\hpcu180t.inf"
Any ideas as to why this won't work when launched from a shortcut?
EDIT:I tried using
& pnputil.exe /add-driver "\\myServer\HP UPD PCL 5\hpcu180t.inf"
as referenced in
Running CMD command in PowerShell
but I still get the error. I also tried
start-process pnputil.exe /add-driver "\\myServer\HP UPD PCL 5\hpcu180t.inf"
but got a similar error that pnputil.exe could not be found.
Both of these options work from a Powershell prompt, but again, fail when launched from a shortcut.
Thank you in advance.
You're invoking a 32-bit instance of PowerShell on a 64-bit system, and that instance doesn't see pnputil.exe (by filename only).
Instead of:
C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe -file MyScript.PS1
use:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -file MyScript.PS1
Folder C:\Windows\SysWOW64 is where the 32-bit executables live.
Paradoxically, for historical reasons, it is C:\Windows\System32 that houses the 64-bit executables.
If, for some reason, you do need to run a 32-bit instance of PowerShell, you can invoke pnputil.exe by its full path:
It only exists as a 64-bit executable in the 64-bit system folder, which 32-bit processes can access as C:\Windows\SysNative:
C:\Windows\SysNative\pnputil.exe

TFS Run PowerShell on Targe Machines not working?

I'm Running powershell script using TFS build step - Run PowerShell on Target Machines but it does not work.
Here's how script looks like:
Start-Process -FilePath 'Bginfo.lnk'
It runs shurtcut that refreshes information on pc desktop using bginfo.exe - script works fine when its executed manualy.
TFS executes that script, but it does not work - bginfo is not refreshed.
If I add to that script line that creates new file it also will be created.
Why it does not automatically update background using specified shurtcut?
I can reproduce this issue. Tried command line, batch script, PowerShell steps with /TIMER:0 /SILENT /NOLICPROMPT set and with the service account which has administrator's privilege. Seems it only works when run the script manually on target machine.
In this case, if you want to refresh the system info automatically, you can use task schedule to run the Bginfo script in target machine. Reference below threads :
BGinfo not running silently
BGInfo on Windows Server 2012
Making BgInfo work in Windows 2012 / Windows 2016

Powershell script failing from teamcity, running fine upon manual run

I have a powershell script which creates a new login in a database.
The script runs fine when I run from powershell ISE or console but it fails when I run it from Teamcity or use teamcity command manually.
C:\windows\sysnative\cmd.exe /c C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NonInteractive -File C:\DB_Deploy\DB_Deploy.ps1 && exit /b %ERRORLEVEL%
The error I get is
Validation Error: Error while checking backup file
The .bak backup file is at a shared remote location.
I suppose the problem, while running from teamcity, is in opening the backup file.
The same runner config works for other powershell scripts, the ones not involving opening of any file on remote location.

powershell remote installation of msi fails

I'm trying to install a msi file on a remote server using powershell.
Server 1 is my build server and server 2 is my application server.
When the build server finishes a buil, I want to trigger a powershell script to install the latest version to my application server.
I'm using the following command to create a session and execute the installation:
# Create session to Application Server
$Session = New-PSSession -Name <ApplicationServer> -ComputerName <ApplicationServer> -Auth CredSSP -cred OURDOMAIN\MyUser
# Prepare expression and create script block
$Script = "Invoke-Expression 'msiexec /i <InstallerFile> /qn /L*v C:\Temp\install_fail.log'"
$ScriptBlock = [Scriptblock]::Create($Script)
# Execute in the session
Invoke-Command -ScriptBlock $ScriptBlock -Session $Session
# Clean up the session
Remove-PSSession $Session
The log has the following error (see attachment install_fail.log for full log)
MSI (s) (C4:1C) [17:08:05:333]: Note: 1: 1708
MSI (s) (C4:1C) [17:08:05:333]: Product: WindowsService1 -- Installation failed.
MSI (s) (C4:1C) [17:08:05:335]: Windows Installer installed the product. Product Name: WindowsService1. Product Version: 8.0.0.0. Product Language: 1033. Manufacturer: MyCompany. Installation success or error status: 1603.
When I start a session on the powershell command promt and execute the installation the installation succeeds (see attachment install_success.log for full log):
ENTER-PSSession -ComputerName
Invoke-Expression 'msiexec /i /qn /L*v C:\Temp\install_success.log'
exit
When I print whoami in both cases it returns OURDOMAIN\MyUser.
Microsoft lists the following regarding the 1603: (http://support.microsoft.com/kb/834484)
The folder that you are trying to install the Windows Installer package to is encrypted.
The folder is not encrypted
The drive that contains the folder that you are trying to install the Windows Installer package to is accessed as a substitute drive.
The drive is a partition on the harddisk of the server
The SYSTEM account does not have Full Control permissions on the folder that you are trying to install the Windows Installer package to. You notice the error message because the Windows Installer service uses the SYSTEM account to install software.
The SYSTEM account has Full Control on the drive and all folders.
Please advise...
Have you tried using PSEXEC? or are you using powershell for a reason? I find that easier for remote installs than trying to go through powershell.
Just PSEXEC into the server CMD. Copy the files locally then run MSIExec to install.
I ended up writing a second PowerShell script that runs on the server watching a specific folder for new msi files. The script runs the first script that actually performs the installation tasks.