TF history - prompt user - visual-studio

I want to prompt only username/author of last changeset. It is possible?
tf history . /r /noprompt /stopafter:1

I don't think we can prompt only the username/author of the latest changeset by running the History command. Basically, the command will list the Changeset, User,Dateand Comment. See History command for details.
However you can try to write a script to run the command and retrieve the Author only if possible.
Besides, you can also achieve that by calling the Get Changesets REST API in a script.
Below PowerShell script for your reference:
$collectionurl = "https://xxx/DefaultCollection"
$project = "ProjectName"
$user = ""
$token = "PAT"
# Base64-encodes the Personal Access Token (PAT) appropriately
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))
$changeseturl = "$collectionurl/_apis/tfvc/changesets?searchCriteria.itemPath=$/$project&api-version=6.0"
$result = (Invoke-RestMethod -Uri $changeseturl -Method Get -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)}).value | Select -first 1
Write-host "The last changeset author is:" $result.author.displayName

Related

How to display the output (query result) from an update query which is executed by a powershell script?

On a daily basis, I need to update certain number of records in a DB.
Now to update this DB, I am using Merge --> Select--> Update sequentially.
But I need to display the output from this update statement (in a log file)
Code: update_status.ps1
$FilePath = $HOME+"\bin\ORACLE_CONNECTION_HOME\oracle_config.properties"
$SID=Select-String -Pattern "oracle_SID" -Path $FilePath
$Data_Source=$SID.ToString().split('=')[1]
$user_name=Select-String -Pattern "oracle_user_name" -Path $FilePath
$User=$user_name.ToString().split('=')[1]
$user_password=Select-String -Pattern "oracle_user_password" -Path $FilePath
$Pwd=$user_password.ToString().split('=')[1]
$connectionString= "Data Source=$Data_Source;User Id=$User;Password=$Pwd;Integrated Security=no"
[System.Reflection.Assembly]::LoadWithPartialName("System.Data.OracleClient") | Out-Null
$connection = New-Object System.Data.OracleClient.OracleConnection($connectionString)
function Oracle_Connection ( $query)
{
$connectionString= "Data Source=$Data_Source;User Id=$User;Password=$Pwd;Integrated Security=no"
[System.Reflection.Assembly]::LoadWithPartialName("System.Data.OracleClient") | Out-Null
$connection = New-Object System.Data.OracleClient.OracleConnection($connectionString)
$queryString = $query
$command = New-Object System.Data.OracleClient.OracleCommand($queryString, $connection)
$connection.Open()
$dataset = New-Object System.Data.DataTable
$oracleadapter = New-Object System.Data.OracleClient.OracleDataAdapter $command
$resultcount = $oracleadapter.fill($dataset)
$result = $command.ExecuteScalar()
Write-Host $result
$connection.Close()
}
function Update_p2c ($p2c, $c2p)
{
Write-Host "Updating P2C"
$query_sub_p2c ="MERGE INTO TABLE TB USING (SELECT ...) src ON ( NAME = src.NAME) WHEN MATCHED THEN UPDATE SET TB.P2C = src.ID";
Oracle_Connection $query_p2c
if ($resultcount -gt 0) { Write-Host "$resultcount rows were updated"} else {Write-Host "No rows were updated"}
}
##Initial setup completed.
#Defining Source and Target variables used in functions
$p2c = 'P2C'
$c2p = 'C2P'
Update_p2c -p2c $p2c -c2p $c2p
##End
Result:
PS D:\
Updating P2C
No rows were updated
However, I see that when I run the select & update manually in DB, I can see the rows getting selected as well as updated respectively.
This script is triggered by a .bat file in a task scheduler and it generates a log file
bat file:
pushd "%~dp0"
start /B /WAIT powershell -File "D:\bin\update_status.ps1" >> D:\log\update_status_%USERNAME%_%date%_log.log 2>&1
exit
My requirement is: I need to get the output from the update ( so and so rows updated from db) into the log file. Even if no rows get updated, it should show the same.
Please let me know if my ask is not clear.
Any help would be greatly appreciated :)
In principle you do not need a batch to run a powershell script from the task scheduler.
Task -> Actions -> Program/script = powershell.exe
Task -> Actions -> Add arguments = -File "D:\bin\update_status.ps1"
If the data you are looking for ist stored in the variable $result, simply wirte it to the logfile:
$result | set-content "D:\log\update_status_$($env:username)_$(get-date -format 'yyyy-dd-MM')_log.log"
Note $env:username will always be the caller identity of the scheduled task.

PowerShell question - webrequest or curl doesn't work with tasks

I've written (partly by myself) a script which get the ip address with a webrequest and save it as variable for a dyndns update. If I start the script via ISE or directly with PowerShell it works as expected. But if I start it via scheduled task the web request, whether with invoke-webrequest or curl doesn't works. The script will be started but the variable is empty. If I try to save the output of the command to a file its also empty, so I don't know why it doesn't work.
Here is the script:
# Get IPv4 and IPv6 from wtfismyip.com
$strIPv6 = Invoke-WebRequest -uri http://[2a01:4f9:4b:4c8f::2]/text | select Content -ExpandProperty Content
$strIPv4 = Invoke-WebRequest -uri http://95.217.228.176/text | select Content -ExpandProperty Content
$strIPs = $strIPv4 + "," + $strIPv6
$strIPs = [string]::join("",($strIPs.Split("`n")))
echo "IPs" >> C:\temp\test.txt
echo $strIPs >> C:\temp\test.txt
$strDYNDNS_URL = "https://dyndns.strato.com/nic/update?hostname=sub.domain.de&myip=$strIPs"
# Debug Informations
write "IPv4: $strIPv4"
write "IPv6: $strIPv6"
write "Strato URL: $strDYNDNS_URL"
# Strato DynDNS Update
$user = "domainuser"
$pass = "pass"
$pair = "${user}:${pass}"
$bytes = [System.Text.Encoding]::ASCII.GetBytes($pair)
$base64 = [System.Convert]::ToBase64String($bytes)
$basicAuthValue = "Basic $base64"
$headers = #{ Authorization = $basicAuthValue }
Invoke-WebRequest -uri $strDYNDNS_URL -Headers $headers
The scheduled task runs for testing with an admin user with the following settings:
Start with highest privileges
Trigger: every hour
Cmd: powershell.exe ExecutionPolicy Bypass -Command "C:\Daten\Scripte\StratoDynDNS-Update.ps1"
Does have anyone an idea why it doesn't work? Or is there a better solution?
The goal is to make a dns update at strato because the ISP of my client doesn't provide static ips, even with a business internet connection.

How to pass the password as parameter in Powershell script

I've got the following parameter setup and trying to pass it into the 7zip password as the script shows. The Reason i've setup the parameter is I need passto contain the current month plus the rest of the password.
Script
$Password = $MonthFull+$year+"#Test"
Start-job -scriptblock {
param($p_output_zip_file, $p_exported_files)
Set-Alias SZ "C:\Program Files\7-Zip\7z.exe"
**SZ a $p_output_zip_file $p_exported_files -sdel -p'Jun2020#Test'** -- I need this to pick up the current month plus the rest of the password
} -name "Compress_File" -ArgumentList "$output_zip_file","$exported_files" | Out-Null
Thanks
$('-p' + ('{0:MMMyyyy}{1}' -f (Get-Date), '#Test'))

How to download artifacts from CircleCI via Powershell command Invoke-RESTMethod

I'm trying to get artifacts from CircleCI in Powershell and getting back an unfamiliar data format?
Powershell likes to auto-convert your API’s JSON response to a PSCustomObject. This normally would be what I want.
Here is an example of my attempts at getting clean data.
Add the necessary .NET assembly
Add-Type -AssemblyName System.Net.Http
Create the HttpClient object
$client = New-Object -TypeName System.Net.Http.Httpclient
Get the web content.
$task = $client.GetByteArrayAsync(“https://circleci.com/api/v1.1/project/$vcs_type/$username/$project/$build_number/artifacts?circle-token=$CIRCLE_TOKEN”)
Wait for the async call to finish
$task.wait();
results:
(({
:path “src./file1.txt”,
:pretty-path “src/file1.txt”,
:node-index 0,
:url “https://15-198716507-gh.circle-artifacts.com/0/src/file1.txt”
} {
:path “src/file2.txt”,
:pretty-path “src/file2.txt”,
:node-index 0,
:url “https://15-198716507-gh.circle-artifacts.com/0/src/file2.txt”
}…continued
As you can see this is not JSON or YAML. Let’s try the built-in PowerShell tools like Invoke-RestMethod.
Invoke-RESTMethod -uri https://circleci.com/api/v1.1/project/$vcs_type/$username/$project/$build_number/artifacts?circle-token=$CIRCLE_TOKEN -Method GET
**Output:**
({
:path “src/file1.txt”,
:pretty-path “src/file1.txt”,
:node-index 0,
:url “https://15-198716507-gh.circle-artifacts.com/0/src/file1.txt”
} {
:path “src/file2.txt”,
:pretty-path “src/file2.txt”,
:node-index 0,
:url “https://15-198716507-gh.circle-artifacts.com/0/src/file2.txt”
}…continued
Dang same output. I know from the Invoke-RestMethod documentation that PS sees JSON and auto converts it to a PS object. Maybe it's converting a data type I'm not familiar with? I found it odd that PowerShell was getting EDN type when every other attempt outside PowerShell was JSON.
Maybe they should have the API updated to reply to PS request with JSON by default.
What is wrong with PowerShell not getting JSON data?
It's EDN, didn't know this until CircleCI answered a question on this topic. So if you are using PowerShell to retrieve artifacts from CircleCI you definitely want to know this.
you need to pass a header specifying the data type returned.
(Accept: application/json)
A CircleCI Support member let me know that in PowerShell you have to specify an Accept header to receive the data in JSON. No wonder I'm getting weird output!
So trying again with the new accept JSON header we have this command below.
Working command to get data in JSON and have it auto-convert to a PSObject.
Invoke-RestMethod -Uri https://circleci.com/api/v1.1/project/$vcs_type/$username/$project/$build_number/artifacts?circle-token=$CIRCLE_TOKEN -Method GET -ContentType 'application/json' -UseBasicParsing -Header #{"Accept" = "application/json"}
OUTPUT
$response|select path,url
path
----
src.orig/file1.txt
src.orig/file2.txt
url
---
https://15-824975-gh.circle-artifacts.com/0/src.orig/file1.txt
https://15-824975-gh.circle-artifacts.com/0/src.orig/file2.txt
Using the PS commands Invoke-WebRequest/Invoke-RestMethod both will receive data in EDN format if you don't do the below. Yay now I can use the data as I see fit to download my artifacts.
Reply from CircleCI that got me the solution.
#burninmedia So what's being sent back is actually a data format called EDN. If you want to return JSON you'll need to pass a header specifying so (Accept: application/json). Thanks!
Here is a simple script I wrote to download all the artifacts. Please be sure you're setting the environment variables.
if ($USERNAME -eq $null) { write-host " please add required variable USERNAME" ;exit }
if ($VCS_TYPE -eq $null) { write-host " please add required variable VCS_TYPE" ;exit}
if ($CIRCLE_TOKEN -eq $null) { write-host " please add required variable CIRCLE_TOKEN" ;exit}
if ($BUILD_NUMBER -eq $null) { write-host " please add required variable BUILD_NUMBER" ;exit}
if ($PROJECT -eq $null) { write-host " please add required variable PROJECT" ;exit}
if ($BASEPATH -eq $null) { write-host " please add required variable BASEPATH" ;exit}
$response = Invoke-RestMethod -Uri https://circleci.com/api/v1.1/project/$VCS_TYPE/$USERNAME/$PROJECT/$BUILD_NUMBER/artifacts?circle-token=$CIRCLE_TOKEN -Method GET -ContentType 'application/json' -UseBasicParsing -Header #{"Accept" = "application/json"}
ForEach ($i in $response){
$PATH = $(Split-Path -Path "$($BASEPATH)\$($i.path)")
if (-Not ( Test-Path $PATH) ) {
write-host "Creating folder: $($PATH)"
New-Item -ItemType Directory -Force -Path "$($PATH)"
}
Write-Host "Saving artifact $($i.pretty_path) to file: $($BASEPATH)\$($i.path)"
Invoke-RestMethod "$($i.url)?circle-token=$($CIRCLE_TOKEN)" -UseBasicParsing -OutFile "$($BASEPATH)\$($i.path)"
}
Bash version
export CIRCLE_TOKEN=':your_token'
echo $(https://circleci.com/api/v1.1/project/$vcs-type/$username/$project/$build_number/artifacts?circle-token=$CIRCLE_TOKEN) > ./artifact_json
for ((i = 0 ; i <= $(jq -c '.[].url ' ./artifact_json|wc -l) ; i++));
do
path=$(jq -c ".[$i].path" ./artifact_json|tr -d '"');
url=$(jq -c ".[$i].url" ./artifact_json|tr -d '"');
pathdir=$(dirname "$path")
echo "URL: $url"
echo "path: $path"
echo "Pathdir: $pathdir"
[ -d $pathdir ] && mkdir -p "$pathdir" #check if folder exists if not mkdir
wget -o $path $url
done
rm ./artifact_json```

Powershell script to run a .bat file when a file is added to a folder

I'd like to monitor a Windows 7 folder and have a .bat file run when any new files are added to the folder. It seems like I should be able to do this using powershell, which is installed on the computer.
I've read some answers like this one but I'm not able to get anything to work yet by modifying what I see. Details:
Folder to monitor:
c:\aaa\bbb\monitorThis
Batch file to run whenever an .htm file is added to the monitored folder:
c:\aaa\bbb\runA.bat
Powershell script file:
c:\aaa\bbb\folderWatcher.ps1
Can someone describe what the content of folderWatcher.ps1 should look like, including the line containing the command to run the .bat file, registering and unregistering the event, and so on?
Also, is right-clicking the .ps1 file and selecting "Run with PowerShell" the way to start the monitoring, and if so, how do you stop it?
UPDATE:
As requested, here is what I have so far for folderWatcher.ps1, but it's just a start, from ideas I've seen:
$folder = "c:\aaa\bbb\toConvert"
$filter = "*.*"
$fsw = new-object System.IO.FileSystemWatcher $folder, $filter -Property #{
IncludeSubDirectories=$false
NotifyFilter = [System.IO.NotifyFilters]'FileName, LastWrite'
}
$onCreated = Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action {
Start-Process cmd -ArgumentList "/c runA.bat" -WorkingDirectory "C:\aaa\bbb"
}
Note: re filtering, I don't care what kind of file is added, since we will only be putting .htm files in that folder, so anything added to it I want to trigger the .bat.
UPDATE II
I tried the code from Dennis below but I get nothing. I just double-checked all my paths to be sure they were the equivalent of what he has. I also just made a new test version with simpler paths so I can post exactly what I have without having to anonymize:
$folder = 'C:\Developer\psTest' # Enter the root path you want to monitor.
$filter = '*.htm' # You can enter a wildcard filter here.
$fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property #{IncludeSubdirectories = $false;NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'}
Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action {
$name = $Event.SourceEventArgs.Name
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
Write-Host "The file '$name' was $changeType at $timeStamp" -fore green
cmd.exe /c 'C:\Developer\psTest\runAnt.bat'
}
To be clear what I'm doing:
I have a file now called C:\Developer\psTest\FolderWatcherTest.ps1 that contains the code directly above.
When I right-click it and select Run with PowerShell, a console window flashes with some text but it's too fast to read before it closes.
When I then drag an .htm file into C:\Developer\psTest, nothing happens.
I put the unregister code into a file called FolderWatcherStop.ps1, and when I click that, the console flashes with some red text, again too quick to read, then it closes.
What am I doing wrong? Something I'm sure.
UPDATE III
Following Dennis's advice I got this working. This took modifying the batch file a little to include the full path of the ANT build I want to run, but it works.
Note: I think I just got why the trigger is repeating, will update.
Here you go:
$folder = 'f:\test' # Enter the root path you want to monitor.
$filter = '*.html' # You can enter a wildcard filter here.
$fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property #{IncludeSubdirectories = $false;NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'}
Register-ObjectEvent $fsw Created -SourceIdentifier FileCreated -Action {
$name = $Event.SourceEventArgs.Name
$changeType = $Event.SourceEventArgs.ChangeType
$timeStamp = $Event.TimeGenerated
Write-Host "The file '$name' was $changeType at $timeStamp" -fore green
write-host "test"
Invoke-Item 'f:\test\test.bat'
}

Resources