How to get current Build definition name using PowerShell in TFS - visual-studio

We are using TFSdeployer to trigger Build deployment to deploy build.
But stuck with how to get Build definition of the current Build for which we trying and could not succeed.
How to get current Build definition name using below PowerShell script instead of hardcode.
Scenario: If i trigger from Test1 BuildQuality then first code should be working . If i trigger from Test2 BuildQuality then second code should be working. (If-Else code is working perfectly)
Tried using $TFSDeployerBuildDetail.DefinitionName
$Build.Name
But that seems to be not working, Any help is appreciated.
$BuildDefinitionName = "Test1"
$PackagePath = "C:\extra\Package_Files"
$DestPath1 ="C:\extra\Test1"
$DestPath2 ="C:\extra\Test2"
$logFile ="C:\extra\logs"
$utilPath = "C:\util\"
if ($BuildDefinitionName -eq "Test1")
{
Write-Host "Testing 1st Copy"
Add-Content -Path $logFile "Copying to Test1"
& $utilPath\robocopy $PackagePath $DestPath1 /s >> $logFile
}
elseif($BuildDefinitionName -eq "Test2")
{
Write-Host "Testing 2nd Copy"
Add-Content -Path $logFile "Copying to Test2"
& $utilPath\robocopy $PackagePath $DestPath2 /s >> $logFile
}

Use the provided environment variable:
$env:BUILD_DEFINITIONNAME
https://learn.microsoft.com/en-us/vsts/build-release/actions/scripts/powershell

Since you indicated you're using XAML build, the environment variable would be $env:TF_BUILD_BUILDDEFINITIONNAME.
The other answer is correct for the newer, web-based build system.

Related

TFS and Microsoft Dynamics 365: Solution Name and Version to corresponding variable in VSTS

Lets say i have a solution named "Dynamics_1_2_3_4.zip".I want the Name, the versions (1,2,3,4) to store in different corresponding variable in VSTS. How do I achieve this?
SolutionName = Dynamics
SolutionVersionMajor = 1
SolutionVersionMinor = 2
SolutionVersionBuild = 3
SolutionVersionRevision 4
My goal is to increment the value on one of the Solution Version. Thanks
As I already answered on GitHub.
You can add a PowerShell step with something like this in it:
"MySolution_1_2_3_4.zip" -match "^(?<name>\w+?)_(?<major>\d+)_(?<minor>\d+)_(?<build>\d+)_(?<revision>\d+).zip$"
Write-Host "##vso[task.setvariable variable=SolutionName;]$($matches['name'])"
Write-Host "##vso[task.setvariable variable=SolutionVersionMajor;]$($matches['major'])"
Write-Host "##vso[task.setvariable variable=SolutionVersionMinor;]$($matches['minor'])"
Write-Host "##vso[task.setvariable variable=SolutionVersionBuild;]$($matches['build'])"
Write-Host "##vso[task.setvariable variable=SolutionVersionRevision;]$($matches['revision'])"
After the step VSTS will have the variables available like $(SolutionVersionBuild)
Refer to these steps below:
Add PowerShell task (Type: Inline Script; Arguments: -p [The folder path of file, such as $(Build.SourcesDirectory)];
Scripts:
param(
[string]$p
)
Write-Host $p
$files=Get-ChildItem -Path "$p\Dynamics*.zip"
$name=$files[0].name.Split('\')[-1]
Write-Host $name
# scripts as Michael said
Note: $(Build.SourcesDirectory) is the local path on the agent where your source code files are downloaded. For example: c:\agent_work\1\s

Remove an entry from credential manager for all users on Windows

I am currently implementing a "remove settings" for all users in a Windows uninstaller and came over an issue I am not even sure is possible to solve.
The application stores credential entries for the current user using the CredentialManager (keymgr.dll). Let's call the target of the credential "X". On uninstall all credentials with stored with target "X" should be removed on all users. The uninstaller of course requires administrator privileges but still I find it very difficult to accomplish this.
For the current user that command is generally solved via cmdkey /delete=:X from a command prompt. As far as I know cmdkey.exe /list only helps to list entries for the current user and can't remove local entries from another user.
I have learned that the credentials are stored as OS files under the C:\Users\_user_\AppData\Local\Microsoft\Credentials folder, but I can't know which files are the entries I want to delete and removing all would be dangerous for other applications. Also I assume removing OS files will be dangerous and could have limitations (extra UAC prompt?) as well.
Runas command is the closest shot I got but because it requires the password of the user it becomes very difficult and not something I would want in the uninstaller. I also would need a way to get the username and domain for each user and iterate them.
I would prefer to use either cmd or powershell for this.
Don't want to necro an old post but I needed to do this myself so I figured I'd add this in case anyone else needs it:
cmdkey /list | ForEach-Object{if($_ -like "*Target:*" -and $_ -like "*microsoft*"){cmdkey /del:($_ -replace " ","" -replace "Target:","")}}
Powershell one liner that will remove any credentials with Microsoft in the string.
Reference:
https://gist.github.com/janikvonrotz/7819990
I ran this and it purged it locally without needing to run as admin (but I am a local admin)
The cmdkey.exe utility when run from a batch file or a PowerShell command may encounter two issues related to special characters.
1. If run from a batch file, if the credential has "(" or ")" without the double quotes, that is left and right paren, that credential will not be removed.
2. If the credential name aka targetname, has a hyphen surronded by spaces the cmdkey will not remove or create a a credential with that string " - ".
There are a few powershell modules written to try and do this, but the only one i found that handles this exceptions was on Github
https://github.com/bamcisnetworks/BAMCIS.CredentialManager
BAMCIS.CredentialManager
Using this i was able to create credentials to set up a test environment with parens or hyphens, but more importantly to remove them by gathering the users list of cached credentials using the modules command and then passing the information in the command to the remove command to remove ALL cached credentials.
One caveat. After removing the command, after some period of time two cached credentials dynamically reappear.
So to address frequent user lock out issues i am going to try and deploy this using SCCM under user context at logoff. Otherwise a system restart after removing the credentials may be needed.
Here is a prototype script that imports the module and then uses it to remove all cached credentials, As always, test, test, test and use at your own risk!
Clear-host
import-Module "$PSScriptRoot\BAMCIS.CredentialManager\BAMCIS.CredentialManager.psd1"
$L = Get-CredManCredentialList -ErrorAction SilentlyContinue
If($L -eq $null)
{
Write-host "No Cached Credentials found to remove, no action taken"
$LASTEXITCODE = 0
Write-host "The last exit code is $LASTEXITCODE"
}
Else
{
ForEach($cred in $L)
{
Write-host "`tProcessing...`n"
Write-host "$($cred.TargetName.ToString())`n"
Write-host "$($cred.Type.ToString())`n`n"
$R = Remove-CredManCredential -TargetName $($cred.TargetName.ToString()) -Type $($cred.Type.ToString()) -Force
}
$L = Get-CredManCredentialList -ErrorAction SilentlyContinue -ErrorVariable $Cred_Error
If($L -eq $null)
{
Write-host "All Cached Credentials removed, program Complete"
$LASTEXITCODE = 0
Write-host "The last exit code is $LASTEXITCODE"
}
Else
{
Write-host "WARNING: One or more Cached Credentials were not removed, program Complete"
$LASTEXITCODE = 1
}
}
Batch, elevated cmd prompt:
To find the main ones, lists any with MS.O, Micro and teams:
for /f "tokens=1-4 Delims=:=" %A in ('cmdkey /list ^| findstr Target: ^| findstr /i "MS.O Micro Teams"') do #echo %D
This deletes all the entries for teams:
for /f "tokens=1-4 Delims=:=" %A in ('cmdkey /list ^| findstr /i teams') do #cmdkey /delete:%D
If you want to include this as a script the syntax will be slightly different. Double the %%A %%D vars
Ran into similar issue, clearing old credentials for non domain joined devices. Created logon task to clear credentials. In my case was looking for particular file server, so not to clear all creds by accident. Because of syntax issue when piping string expressions into task, was easier to create reference .ps1 then reference in task. Pushed this script through Intune....
# Full path of the file
$file = 'C:\script\clearcreds.ps1'
#If the file does not exist, create it.
if (-not(Test-Path -Path $file -PathType Leaf)) {
try {
$null = New-Item -Path "C:\ProgramData\CentraStage\Packages" -Name
"clearcreds.ps1" -ItemType "file" -Value 'cmdkey /list | ForEach-Object{if($_ -
like "*Target:*" -and $_ -like "*fileserver*"){cmdkey /del:($_ -replace " ","" -replace "Target:","")}}'
Write-Host "The file [$file] has been created."
}
catch {
throw $_.Exception.Message
}
}
#######################################
#Create ScheduledTask to Run at log on.
#######################################
$schtaskName = "Clear Cached Creds "
$schtaskDescription = "Clears Cached Creds for each user at logon."
$trigger = New-ScheduledTaskTrigger -AtLogOn
$class = cimclass MSFT_TaskEventTrigger root/Microsoft/Windows/TaskScheduler
#Execute task in users context
$principal = New-ScheduledTaskPrincipal -GroupId "S-1-5-32-545" -Id "Author"
$action3 = New-ScheduledTaskAction -Execute 'Powershell.exe' "-File C:\script\clearcreds.ps1"
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries
$null=Register-ScheduledTask -TaskName $schtaskName -Trigger $trigger -Action $action3 -Principal $principal -Settings $settings -Description
$schtaskDescription -Force
Start-ScheduledTask -TaskName $schtaskName

Can I add a custom step to a nuget install

I'm investigating ways to allow many website projects to pull from the same collection of CSS/JS/HTML and have that collection be updated once and then delivered to all the projects that use it.
At the moment, I'm exploring using a NuGet package (my company uses TFS and VS so it seems the logical package manager) to deliver the styles, and using the content folder to deliver the files directly into the project. However, each project is going to need those files in different locations in order to work properly.
Is there a way to add a custom script to a post-install/update of a NuGet package for each project?
For those of you in the future:
In your package: tools/install.ps1
param($installPath, $toolsPath, $package, $project)
$projectFullName = $project.FullName
$debugString = "install.ps1 executing for " + $projectFullName
Write-Host $debugString
$fileInfo = new-object -typename System.IO.FileInfo -ArgumentList $projectFullName
$projectDirectory = $fileInfo.DirectoryName
$customInstallFile = $projectDirectory + "\" + $package.Id + ".ps1"
Write-Host "looking for" $customInstallFile
if(Test-Path $customInstallFile){
Write-Host "found it"
& $customInstallFile
} else {
Write-Host "not found"
}
Write-Host "Installation Complete"
And in your project's root folder: [packageId].ps1
Write-Host "Hello world!"

PowerShell: Invoke-Parallel throwing error with "start-process"

I'm using the Invoke-Parallel CmdLet that can be found at the link here. When I have some dummy code in my script block, it works correctly, but when I add a start-process... command it fails with an error saying
Get-RunspaceData : This command cannot be run due to the error: The system
cannot find the file specified.
At c:\crm\Interfaces\Batches\Invoke-Parallel.ps1:592 char:13
My script block looks like so. Long story short, I'm feeding file names into a block, and I am telling a 3rd party application to use that file as an input for a process. When the start-process line is removed, it works, with it, it fails.
$childFiles| Invoke-Parallel -ImportVariables {
$importformat = '-f ' + '"CU Imp P19 FI"'
$importfile = '-d ' + $_ + " " + $user + " " + $pass
Write-Host $importformat + " " + $_
start-process .\mmim.exe -ArgumentList $user, $pass, '-l:1',
$importformat, $importfile -Wait -NoNewWindow
return "blah"
}
Does anyone have any idea of what might be going on? My PowerShell version is the following
Major:5
Minor:0
Build: 10586
Revision: 117
Any help is greatly appreciated.
Each PowerShell runspace have its own current location. If Invoke-Parallel does not change current location of spawned runspaces to match current location of main runspace, then relative path .\mmim.exe may be resolved to entire different executable or not resolved at all and produce given error.

Teamcity 8- treat a build parameter as long or integer

Using teamCity 8.0.5.
As part of my builds cleanup I would like to automatically remove any build older than the current 5 builds. For eg if my build.number = 12 , try and remove build 6.
Unfortunately it seems that you can't cast %build.number%-6.
Using Teamcity how can you perform math on a build parameter?
I have tried
%build.number% -1 along with wrapping it in ()
%system.PreviousBuild% = \\server\path\Build%build.number%-6
my actual usage of this a command line post build event:
echo trying to remove directory %system.PreviousBuild%
IF EXIST %system.PreviousBuild% RD %system.PreviousBuild% /Q /S
result:
[09:19:09][Step 6/6] trying to remove director \server\path\Build11-6
-------------------------UPDATE---------------------------
the answer below led me to the following solution:
NOTE: The important part here is to cast the build.number as an integer.
using powershell source code build step
Using powershell for the entire command worked for me:
Set-Variable -Name previousBuild -Value (([int]%build.number%)-6).ToString()
Write-Output $previousBuild
Write-Output $env:PreviousBuildPath
Set-Variable -Name path -Value $env:PreviousBuildPath$previousBuild
Write-Output $path
if((Test-Path -path $path))
{
Remove-Item -Recurse -Force $path
}
set /a newBuildNumber=%build.number%-6
Then use %%newBuildNumber%% in your TC build script after the path.
\\server\path\Build%%newBuildNumber%%

Resources