Linking pull requests to the workitems from the TFS database - sql-server

We use custom queries (against TFS databases: Tfs_DefaultCollection and Tfs_Warehouse) to check if all changesets have a workitem linked to it. We use the FactWorkItemChangeset table from the Tfs_Warehouse database.
Currently we are migrating to TFS Git and we want to update our custom queries to check if all the pull requests have a workitem linked to it.
For example:
Git pull request and its workitem
We don't know where in the Tfs_Warehouse or in the Tfs_Defaultcollection database the pull request is linked to the workitem. Does anyone know where this link is stored?

Cannot find the related table, however you can use the REST API to check if all the pull requests have a workitem linked to it. Please see Get Pull Requests By Project and Pull Request Work Items - List for details.
For example, below PowerShell script will retrieve all the Pull Requests from a specific project and list the linked work items for each of them, also output the Pull Requests which have no linked work items to a *.csv file ("D:\temp\1030.csv" in below sample).
Param(
[string]$collectionurl = "http://172.17.16.163:8080/tfs/DefaultCollection",
[string]$project = "GitTest",
[string]$user = "Domain\user",
[string]$token = "password"
)
# Base64-encodes the Personal Access Token (PAT) appropriately
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))
#Get pull request list for a specific project
$prsurl = "$collectionurl/$project/_apis/git/pullrequests?api-version=2.0"
$prs = (Invoke-RestMethod -Uri $prsurl -Method Get -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)})
$prurls = $prs.value.url
#Get the associated work items to PRs
Clear-Host
foreach ($prurl in $prurls)
{
$baseurl = "$prurl/workitems"
$prwis = Invoke-RestMethod -Uri $baseurl -Method Get -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)}
write-host "Pull Reuquest:" $prurl
write-host "Count of Associated Work Items:"$prwis.count
foreach ($prwi in $prwis.value )
{
Write-Host "Associated workitem:"$prwi.id - $prwi.url
}
write-host `n
if ($prwis.count -lt 1)
{
#Write-host $prurl
# Output the Pull Requests which have no work items associated:
$prurl | Add-Content "D:\temp\1030.csv"
}
}

We finally found the link in de Tfs_DefaultCollection.WorkItemFiles! For example: select *
from [dbo].[WorkItemFiles]
where FilePath = 'vstfs:///Git/PullRequestId/4f39e226-6f44-4e56-a216-f45969d8147d%2fab3368e0-56ef-468f-8e14-43065c433a21%2f2619'
This yields this result:
ID 427787
FilePath vstfs:///Git/PullRequestId/4f39e226-6f44-4e56-a216-f45969d8147d%2fab3368e0-56ef-468f-8e14-43065c433a21%2f2619
The ID column contains the workitem id and the FilePath 2 hashes (separated by '%ef') and finally the pull request id. In this example workitem 427787 is linked to pull request 2619.

Related

Exporting all the attributes from Azure AD B2C into a csv

I'm trying to export AAD users from ADB2C to a csv file. I'm able to achieve this using the graph API "graph.windows.net" and some filter conditions. But with this approach, I can only get a limit of 999 records per response and I need to get the next link to do another API call and so on...
This process is taking a long time to fetch the AAD users. Hence I tried using Power shell scripts i.e using Get-AzureADUser, using this approach I was able to get all the users within a short duration. But the issue in this approach I'm not able to get all the attributes that I get via the rest call (i.e the attribute is userIdentites).
The reason I'm looking for userIdentites is, that I can filter out the users with social logins like gmail.com or facebook.com
How can I achieve this using PowerShell scripts? or using CLI or Python?
A sample response from the Graph API -
Powershell script to get the same attributes, but I'm getting blank userIdentites, which is wrong. Expected is few users are to get social logins as shows in Graph API Response
For($i=$index; $i -lt $regexArray.Length; $i++){
$regexArray[$i] | Out-File $tempLogFile -NoNewline
$blobFileName = $fileName + $i + ".csv"
Write-Output ("Exporting Users Information in a CSV File for Surname with Regex : " + $regexArray[$i])
Get-AzureADUser -All $true | where-Object { $_.Surname -cmatch $regexArray[$i]} |
select otherMails,DisplayName,userIdentites,UserPrincipalName,Department | Export-Csv $tempfilepath -NoTypeInformation
Set-AzureStorageBlobContent -Context $context -Container $container -File $tempfilepath -Blob $blobFileName -Force
Write-Output ("Exported File Name : " + $blobFileName)
Set-AzureStorageBlobContent -Context $context -Container $container -File $tempLogFile -Blob $logFile -Force
Write-Output ("Exporting completed for Surname with Regex : " + $regexArray[$i])
}
public static async Task ListUsers(GraphServiceClient graphClient)
{
Console.WriteLine("Getting list of users...");
try
{
// Get all users
var users = await graphClient.Users
.Request()
.Select(e => new
{
e.DisplayName,
e.Id,
e.Identities
})
.GetAsync();
// Iterate over all the users in the directory
var pageIterator = PageIterator<User>
.CreatePageIterator(
graphClient,
users,
// Callback executed for each user in the collection
(user) =>
{
Console.WriteLine(JsonSerializer.Serialize(user));
return true;
},
// Used to configure subsequent page requests
(req) =>
{
Console.WriteLine($"Reading next page of users...");
return req;
}
);
await pageIterator.IterateAsync();
}
catch (Exception ex)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(ex.Message);
Console.ResetColor();
}
}
https://learn.microsoft.com/en-us/samples/azure-samples/ms-identity-dotnetcore-b2c-account-management/manage-b2c-users-dotnet-core-ms-graph/

How to get the Azure AD objectid of the signed in user?

I'm trying to invoke an ARM template that requires a PrincipalId of the currently signed in user.
https://learn.microsoft.com/en-us/azure/templates/microsoft.keyvault/vaults
I've signed in using powershell, as a guest account in the organisation's AAD.
When I check the resulting context, I get:
Name : [sky.sigal#ministryof.me, 5f813400-5b93-43b0-af8f-5fd04714f1ef]
Account : me#here.com
SubscriptionName : SomeSubscriptionName
TenantId : e6d2d4cc-b762-486e-8894-4f5f540d5f31
Environment : AzureCloud
I'm wondering how to get the AAD ObjectId from the above, without string parsing "Name"?
Note that the documentation for the ARM Template is not very clear so not sure if me#here.com would work just as well (am assuming it's talking about a Guid).
Thank you.
You can also get it using the azure cli
az ad signed-in-user show --query objectId -o tsv
You could try Get-AzureRmADUser to get the ObjectId .
Sample:
Get-AzureRmADUser -UserPrincipalName "xxxx#xxxx.com"
Result:
The Id is the ObjectId, you could get it. Also, you could get it via other properties, not only -UserPrincipalName, just refer to the link of the command.
Update:
If you use a Guest account, you could try the command below.
Get-AzureADUser | ?{$_.UserType -eq "Guest"} | ?{$_.UserPrincipalName -like "*partofyouraccount*"}
Note: Before using this command, you need to install Azure AD powershell module.
The info on "Name" you are seeing is related to the subscription. Use the command below to get the objectId under "Account":
(Get-AzContext).Account.ExtendedProperties.HomeAccountId.Split('.')[0]
I am not an expert in AAD but I have found that my own personal Azure subscription unrelated to my work one returns nothing for the following command:
# does not work sometimes
(Get-AzADUser -UserPrincipalName (Get-AzContext).Account).Id
However I found that I can reliably get my user principal name (UPN) and object ID using the Az CLI to get an access token then the Microsoft Graph API to each back the user information.
$token = Get-AzAccessToken -Resource "https://graph.microsoft.com/"
$headers = #{ Authorization = "Bearer $($token.Token)" }
Invoke-RestMethod https://graph.microsoft.com/v1.0/me -Headers $headers
With Powershell cmdlets:
$myObjectId = (Get-AzADUser -UserPrincipalName (Get-AzContext).Account).Id

How to know permissions to other apis of my app

How to know the permissions of my azure ad app have for other APIs, such as Microsoft Grahp API .
In portal , i could check that in the [API Access]-->[Required permissions] , but how do i check that with powershell , i used
Get-AzureRmADApplication -ObjectId ,
Get-AzureRmADApplication -ObjectId xxxxx | fl *
But little attributes returned and AppPermissions is null , but with fiddle , i notice it use below request :
GET https://graph.windows.net/mytenant/applications/id?api-version=1.6 HTTP/1.1
And i could find a lot of attributes of that app ,which one shows the permission of the app and how do i get that in powershell ?
You could try the Azure Active Directory PowerShell Version 2 , the use command like :
$app = Get-AzureADApplication -Filter "appId eq '$appId'" | fl *
to get the RequiredResourceAccess claim ,that is the collection that is shown under "permissions to other applications" in the azure ad classic portal and "Required permissions" in new portal .
In addition , PowerShell essentially wraps the API's and just presents them to you in a simplified interface. If you don't find a command to do what you want you can always using PowerShell to invoke the Graph API directly. Please refer to below article for how to call Azure Active Directory Graph Api from Powershell :
https://blogs.technet.microsoft.com/paulomarques/2016/03/21/working-with-azure-active-directory-graph-api-from-powershell/
And here is a test code sample :
PS C:\Users\v-nany> $header = #{
>> 'Content-Type'='application\json'
>> 'Authorization'=$token.CreateAuthorizationHeader()
>> }
PS C:\Users\v-nany> $uriSAs = "https://graph.windows.net/xxxxxxx/applications/xxxxxx?api-version=1.6 "
PS C:\Users\v-nany> $appInfo = (Invoke-RestMethod -Uri $uriSAs –Headers $header –Method Get –Verbose)
PS C:\Users\v-nany> $appInfo.requiredResourceAccess
You will get resourceAppId represents the resource , and related resourceAccess which is a scope list.

How to upload database using Dropbox?

I've just created a Barcode Scanner app and have a database of barcode. I want to upload/sync this database to the company's server then another programmer can get and build website UI. Unfortunately, our server is not public (but it can connect internet through proxy), so I want to use Dropbox to do that. Could you please give me a useful sample code or tell me the best way to upload/sync database in this case? I am extremely grateful for your help!
Alright, assuming your database is a MySQL DB with a host environment that lets you run cron jobs, access your FTP, etc... here's a possible code snippet for you, I just had to do this myself with the Dropbox API, you can actually read the full post here for a walk-thru (Dropbox API and MySQL DB Dump/Upload
<?php
# Include the Dropbox SDK libraries
require_once __DIR__."/dropbox-sdk/lib/Dropbox/autoload.php";
use \Dropbox as dbx;
//your access token from the Dropbox App Panel
$accessToken = 'NOT-A-REAL-TOKEN-REPLACE-THIS-QM8jS0z1w1t-REPLACE-THIS-TOKEN';
//run the MySQL dump and zip;
// location of your temp directory
$tmpDir = "your_temp_dir";
// username for MySQL
$user = "DB_user";
// password for MySQL
$password = "DB_password";
// database name to backup
$dbName = "DB_name";
// hostname or IP where database resides
$dbHost = "your_hostname";
// the zip file will have this prefix
$prefix = "sql_db_";
// Create the database backup file
$sqlFile = $tmpDir.$prefix.date('Y_m_d_h:i:s').".sql";
$backupFilename = $prefix.date('Y_m_d_h:i:s').".tgz";
$backupFile = $tmpDir.$backupFilename;
$createBackup = "mysqldump -h ".$dbHost." -u ".$user." --password='".$password."' ".$dbName." --> ".$sqlFile;
//echo $createBackup;
$createZip = "tar cvzf $backupFile $sqlFile";
//echo $createZip;
exec($createBackup);
exec($createZip);
//now run the DBox app info and set the client; we are naming the app folder SQL_Backup but CHANGE THAT TO YOUR ACTUAL APP FOLDER NAME;
$appInfo = dbx\AppInfo::loadFromJsonFile(__DIR__."/config.json");
$dbxClient = new dbx\Client($accessToken, "SQL_Backup");
//now the main handling of the zipped file upload;
//this message will send in a system e-mail from your cron job (assuming you set up cron to email you);
echo("Uploading $backupFilename to Dropbox\n");
//this is the actual Dropbox upload method;
$f = fopen($backupFile, "rb");
$result = $dbxClient->uploadFile('/SQL_Backup/'.$backupFilename, dbx\WriteMode::force(), $f);
fclose($f);
// Delete the temporary files
unlink($sqlFile);
unlink($backupFile);
?>
You also need to make a config.json file like so:
{
"key": "YOUR_KEY_FROM_DROPBOX_APP_PANEL",
"secret": "YOUR_SECRET_FROM_DROPBOX_APP_PANEL"
}
You will need to create a new Dropbox app under your Dropbox account to get your key and secret, and to generate the auth code for your username, do that here when logged in: https://www.dropbox.com/developers/apps
You also need to download the Dropbox PHP SDK library to put on your server in the same folder as this PHP code above, find that here: https://www.dropbox.com/developers/core/sdks/php
Hope this helps; if you need more step-by-step or your developer does, go that link at the top for a full walk through.

Powershell 2.0 Ping list of computers and send email on failure

I am new at PowerShell and I have been researching this issue, but I have not been able to find what I am looking for yet. The site is still using PowerShell 2, and it cannot be upgraded.
I have a list of servers that I want to ping to verify that they are up, and I am using a text file to populate the names. I have the pinging part of the script working and the emailing part working just fine. Now I am trying to combine the two to email about a specific server that fails.
I am using the following:
Test-Connection -ComputerName (Get-Content Computers.txt) -Delay 5 -Quiet
This returns the boolean values of true or false for each computer.
I know that the Get-Content automatically creates an array. So is the best way to get the results written as an associative array, or is there a way to get the Test-Connection to loop one at a time through the Computers.txt array and then just send the email on a failure when it is on that specific server?
Try this:
Get-Content Computers.txt | ForEach-Object {
if (Test-Connection -ComputerName $_ -Delay 5 -Quiet) {
#Send email that it was a success
} else {
#Computer unreachable
}
}
Basically you pipe the list of computers to a foreach-object loop, and iterate through the list, pinging each computer and sending the email.

Resources