TFS build fails when running custom powershell script - powershell

I've added a Powershell script step to my on-premises TFS 2015 build definition. The script modifies assembly version in AssemblyInfo.cs file.
I tested the script with the Build Agent account in PowerShell ISE and it worked fine. However, the PowerShell step fails in TFS build with an access denied error.
The Build Agent account has full control permission to C:\agent\_work\11\s\source\MyProject\Properties folder.
Get-Content : Access to the path 'C:\agent_work\11\s\source\MyProject\Properties' is denied.
At C:\agent_work\11\s\source\MyProject\BuildScript\Update-AssembyInfoFile.ps1:64 char:10
+ (Get-Content $file) |
+ ~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (C:\agent_work...MyProject\Properties:String) [Get-Content], Unauthorized
AccessException
+ FullyQualifiedErrorId : GetContentReaderUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetContentCommand

The script error was caused by missing the file name in the file path. The message Access to the path 'C:\agent_work\11\s\source\MyProject\Properties' is denied is kind of confusing but it gives you idea that the file name is missing in the path. The path in the error message is a folder name rather than a filename. Hence, the error occurred.

Related

Copy a file to a directory outside of a GitHub Action Runner directory within a Powershell script

I have a self-hosted GitHub Action Runner that builds a Visual Studio solution and then launches a powershell script that lives inside the repo. This script modifies some files in the repo. I would like these modified files to also be copied to a folder outside the GitHub Action Runner directory as the last step of my action within my PC (Windows 10). This is what the launched script looks like:
$scriptFile = Get-Item ".\SFDScripts\Internal\Hardcore\Hardcore.cs"
$maps = Get-ChildItem ".\SFDScripts\Internal\Hardcore\Maps\"
foreach ($map in $maps) {
if ($map.PSIsContainer) { continue }
# This modifies the file at {$map.FullName}
SFDScriptInjector $scriptFile.FullName $map.FullName
# Then I want to copy that file to a specific directory on the device where the GitHub Action Runner runs
Copy-Item $map.FullName "C:\Users\juans\OneDrive\Documents\Superfighters Deluxe\Maps\Custom"
}
I am currently getting an error at the Copy-Item $map.FullName "C:\Users\juans\OneDrive\Documents\Superfighters Deluxe\Maps\Custom" line. The error is the following
Copy-Item : Access is denied
At E:\actions-runner\_work\SFDScripts\SFDScripts\injectScriptToAllMaps.ps1:7 char:5
+ Copy-Item $map.FullName "C:\Users\juans\OneDrive\Documents\Superf ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Copy-Item], UnauthorizedAccessException
+ FullyQualifiedErrorId : System.UnauthorizedAccessException,Microsoft.PowerShell.Commands.CopyItemCommand
Error: Process completed with exit code 1.
I also tried running the script using this run_as.ps1 script. This allows the Action to finish without errors, but the files are still not copied (I'm guessing it fails silently inside the new instance of powershell.
Here is the .yml action file at its current state.
I can't find out how to give access to the github runner to modify external directories. So, how can I make it to copy the file to an external directory?
What needs to be changed is actually the concerned folder Security parameters. In this case I went to the folder at "C:\Users\juans\OneDrive\Documents\Superfighters Deluxe\Maps\Custom" then did the following:
Right Click on folder > Properties > Security Tab > Advanced > Add > Select a principal > Advanced... > Find Now
In the list under Search Results: search for an entity with a name like GITHUB_ActionsRunner_[short-id].
OK > OK
Choose the permissions you want the Github Action Runner to have on this folder, in my case: Full Control
OK > OK > OK
Then I re runned the Github Action, and the script was launched without any problems

Exception calling "ExtractToFile" when unzipping

I've tried a couple of solutions to unzip a file containing the path:
\Content\F_C\Jenkinsworkspace\workspace\BUILD.PROJECT.GENERICS\PROJECT_Generics\PROJECT.Generics\PROJECT.Generic\obj\Debug\Package\PackageTmp
but I get the error:
Exception calling "ExtractToFile" with "3" argument(s): "Could not find a part of the path
Expand-Archive -LiteralPath F:\Jenkinsworkspace\workspace\BUILD.GENERIC.GENERICS\GENERIC.Generic.zip -DestinationPath F:\Jenkinsworkspace\workspace\BUILD.GENERIC.GENERICS\UNZIPED2 -Force
Exception calling "ExtractToFile" with "3" argument(s): "Could not find a part of
the path 'F:\Jenkinsworkspace\workspace\BUILD.GENERIC.GENERICS\UNZIPED2\Content\
F_C\Jenkinsworkspace\workspace\BUILD.GENERIC.GENERICS\GENERIC_Generics
\GENERIC.Generics\GENERIC.Generic\obj\Debug\Package\PackageTmp\modules\
_protected\EPiServer.GoogleAnalytics\EPiServer.GoogleAnalytics.zip'."
At
C:\Windows\system32\WindowsPowerShell\v1.0\Modules\Microsoft.PowerShell.Archive\Microsoft.PowerShell.Archive.psm1:1033 char:25
+ ... [System.IO.Compression.ZipFileExtensions]::ExtractToFile( ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DirectoryNotFoundException
I'm guessing it's because I have a zip within a zip.
In our case, though the path was short, we were getting the same error.
Sharing our solution which might be useful for someone.
We were trying to unzip the package on our application server through powershell script. Basically powershell script runs on our build server & remotely connect to our application server. It was then trying to unzip the package present on application server.
The above scenario was working fine for quite some time before it starts to throw the error during unzipping.
Solution:
We found the reason was anti virus policy, which was blocking the unzipping through remote powershell script.
Soved using this Blog :
https://www.howtogeek.com/266621/how-to-make-windows-10-accept-file-paths-over-260-characters/
changing the group policy solved the problem

Powershell [system.reflection.assembly].loadfile() Exception Access is denied when run by Jenkins

I have a very simple Powershell script which I want to use as part of a Jenkins build to return Assembly information. The script contains the following:
Write-Host([system.reflection.assembly]::loadfile($args[0])).FullName
When I try and call this script as part of the Jenkins build I get the following errors:
.\GetAssemblyInfo.ps1
Exception calling "LoadFile" with "1" argument(s): "Access is denied.
(Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))"
At C:\Jenkins\workspace\Tools\NuGetBuildSupport\GetAssemblyInfo.ps1:1 char:50
+ Write-Host([system.reflection.assembly]::loadfile <<<< ($args[0])).FullName
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : DotNetMethodException
The command runs fine when it is not executing as part of the Jenkins build.
The DLL that is being passed to loadfile is not marked as Blocked
The execution policy I am using to invoke Powershell is Bypass
I recommend navigating to your servers "Services" select the Jenkins service and you can assign a specific user. As a test try giving Jenkins administrator access and if that works create another user and restrict access. The fact that it runs fine outside of the Jenkins infrastructure is an indicator for this issue.
Services: (Search for services in the start menu or the common location: C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Administrative Tools)
Navigate to the Jenkins Service
Open the properties
Select the Log in tab and set it to a user with proper permissions (E.g: administrator)

PowerShell script and libeay32.dll with Azure Function App

I'm trying to use a PowerShell script that works on my machine in an Azure Function App.
In short, the script uses a Service Principal profile json to login to Azure and then does some magic to renew my Let's Encrypt SSL certificate.
The script itself is in a file called Register-LetsEncryptCertificateSP.ps1 and I can run it successfully in local PowerShell ISE by calling it like this:
PS C:\tmp\test> .\Register-LetsEncryptCertificateSP.ps1 -Domain dev.mysite.com -RegistrationEmail my#email.com -ResourceGroup my-resourcegroup-name -WebApp my-webapp-name -ServicePrincipalProfilePath "c:\tmp\letsencryptSP.json".
I added Service Principal support to Lee Holmes's script which prompts for Azure account credentials by default: https://www.powershellgallery.com/packages/Register-LetsEncryptCertificate/1.0/DisplayScript
I'm trying to put this script inside a TimerTriggerPowerShell Function App. The script requires following modules: #requires -Modules AcmeSharp, Azure, AzureRM.Websites
Azure and AzureRM.Websites are available by default and I have uploaded ACMESharp to modules/ -directory` but when I run the script in Azure I get the following log:
2017-04-03T09:46:23.499 Function started (Id=015f9081-8bc2-4801-b392-76e53da027f7)
2017-04-03T09:46:23.983 Loaded modules:
/TimerTriggerPowerShell1/modules/ACMESharp/0.8.1/ACMESharp.psd1
/TimerTriggerPowerShell1/modules/ACMESharp/0.8.1/ACMESharp-AWS/ACMESharp-AWS.psd1
/TimerTriggerPowerShell1/modules/ACMESharp/0.8.1/ACMESharp-IIS/ACMESharp-IIS.psd1
/TimerTriggerPowerShell1/modules/ACMESharp/0.8.1/ACMESharp.dll
/TimerTriggerPowerShell1/modules/ACMESharp/0.8.1/ACMESharp.PKI.Providers.OpenSslLib32.dll
/TimerTriggerPowerShell1/modules/ACMESharp/0.8.1/ACMESharp.PKI.Providers.OpenSslLib64.dll
/TimerTriggerPowerShell1/modules/ACMESharp/0.8.1/ACMESharp.POSH-test.dll
/TimerTriggerPowerShell1/modules/ACMESharp/0.8.1/ACMESharp.POSH.dll
/TimerTriggerPowerShell1/modules/ACMESharp/0.8.1/ACMESharp.Providers.AWS.dll
/TimerTriggerPowerShell1/modules/ACMESharp/0.8.1/ACMESharp.Providers.IIS.dll
/TimerTriggerPowerShell1/modules/ACMESharp/0.8.1/ACMESharp.Vault.dll
/TimerTriggerPowerShell1/modules/ACMESharp/0.8.1/AWSSDK.Core.dll
/TimerTriggerPowerShell1/modules/ACMESharp/0.8.1/AWSSDK.Route53.dll
/TimerTriggerPowerShell1/modules/ACMESharp/0.8.1/AWSSDK.S3.dll
/TimerTriggerPowerShell1/modules/ACMESharp/0.8.1/ManagedOpenSsl.dll
/TimerTriggerPowerShell1/modules/ACMESharp/0.8.1/Microsoft.Web.Administration.dll
/TimerTriggerPowerShell1/modules/ACMESharp/0.8.1/Newtonsoft.Json.dll
/TimerTriggerPowerShell1/modules/ACMESharp/0.8.1/x86/libeay32.dll
/TimerTriggerPowerShell1/modules/ACMESharp/0.8.1/x86/ssleay32.dll
/TimerTriggerPowerShell1/modules/ACMESharp/0.8.1/ACMESharp-AWS/ACMESharp-AWS.psm1
/TimerTriggerPowerShell1/modules/ACMESharp/0.8.1/ACMESharp-IIS/ACMESharp-IIS.psm1
2017-04-03T09:46:24.186 Import-Module : The specified module 'AWSPowerShell' was not loaded because no valid module file was found in any module directory.
at <ScriptBlock>, /TimerTriggerPowerShell1/modules/ACMESharp/0.8.1/ACMESharp-AWS/ACMESharp-AWS.psm1: line 17
+ Import-Module
+ _____________
+ CategoryInfo : ResourceUnavailable: (AWSPowerShell:String) [Import-Module], FileNotFoundException
+ FullyQualifiedErrorId : Modules_ModuleNotFound,Microsoft.PowerShell.Commands.ImportModuleCommand
2017-04-03T09:46:24.280 Function completed (Failure, Id=015f9081-8bc2-4801-b392-76e53da027f7)
2017-04-03T09:46:24.343 Exception while executing function: Functions.TimerTriggerPowerShell1. System.Management.Automation: Could not load file or assembly 'file:///D:\home\site\wwwroot\TimerTriggerPowerShell1\modules\ACMESharp\0.8.1\x86\libeay32.dll' or one of its dependencies. The module was expected to contain an assembly manifest.
The app service is running on 32bit. Any ideas how to solve this error?

Open a Solution from the Package Manager Console

I'm trying to automate the process of opening a solution from source control.
I have VS12 open, but no solution or project open. Is it possible to change directories and then open a solution from the Package Manager Console?
(This is kind of beside the point, but in case there is a better way overall to do this) I'm trying to script this so that a powershell module installed via nuget could be run:
PM> Get-MyProject 'SomeName'
The module would then from pwd get the latest source cd into it and open the solution. My module can already get the source, but I'm not able to figure out how to open the solution in powershell. It seems like $dte should be able to do it, but I tried:
PM> $dte.Solution.Open('NugetTest.sln')
I get back the error
Exception calling "Open" with "1" argument(s): " could not be found. (Exception from HRESULT: 0x80030002 (STG_E_FILENOTFOUND))"
At line:1 char:1
+ $dte.Solution.Open('NugetTest.sln')
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : COMException
The default directory for the package manager console (unless you have defined a profile where you change it) is %userprofile%. Probably not the place where your solution sits. If you write a powershell script and place it in your solution directory, then execute it from the Power Shell Console, you can get the path of your solution doing this:
$path = Split-Path -parent $MyInvocation.MyCommand.Path
You can create a solution like this:
$solution = $dte.Solution
$solution.Create("C:\Temp", "MySolution.sln")
The first argument indicates the directory where you want to create the solution, the second one is the name of the solution itself.
To open an existing solution:
$solution = $dte.Solution
$solution.Open("<path to your solution>")
If it doesn't work, your path is probably incorrect.