Expanding fields not working fully on SharePoint Lists - microsoft-graph-api

I am following the documentation for Get metadata for a list.
Querying using either PowerShell or the Graph Explorer fails to fully expand the fields for items in a SharePoint list.
An example of this is a lookup field called Responsible that looks up users in Azure Active Directory (or in SharePoint terms, the column is a Person or Group column, limited to people only).
Once selected via the GUI, it's populated with a display name (although I'd hope for more definitive information to be stored on the back end, like UPN).
When querying the Graph API using the form:
$Uri = "https://graph.microsoft.com/v1.0/sites/$($SPSite.id)/lists/$($ServiceList.id)/items?expand=fields"
$Data = Invoke-RestMethod -Headers #{Authorization = "Bearer $accesstoken"} -Uri $Uri -Method Get -ErrorAction Stop
we get something like this:
#odata.etag : "REMOVED"
Title : Storage Platform
Description : Central storage platform
ResponsibleLookupId : 14
Responsible2LookupId : 13
AccountableLookupId : 3
Features : NFS
AudienceLookupId : 92
RequestProcess : {#{LookupId=1; LookupValue=Service Desk}}
Support : {#{LookupId=1; LookupValue=Service Desk}}
AvailabilityLookupId : 1
DependsOn : {}
O365GroupLookupId : 87
LifecycleStageLookupId : 2
ConsultLookupId : 88
id : 1
ContentType : Item
Modified : 2017-11-17T10:47:07Z
Created : 2017-11-17T10:47:07Z
_UIVersionString : 1.0
Attachments : False
Edit :
LinkTitleNoMenu : Storage Platform
LinkTitle : Storage Platform
ItemChildCount : 0
FolderChildCount : 0
_ComplianceFlags :
_ComplianceTag :
_ComplianceTagWrittenTime :
_ComplianceTagUserId :
You can see that the field ResponsibleLookupId just gives a value of 14 which is not useful. Other fields link to Office 365 Groups, but again return values. As such it's impossible to link any of this data to users/groups and is very limited in value except when looking at it through the portal.
How do we expand this data? Will it be provided by the API call at a later date, or do we have to perform further look ups?

By default, Microsoft Graph will return the LookupId for lookup fields. You can ask it to provide the actual value by specifically requesting that field in a $select parameter.
Using the following query will return the displayName rather than the LookupId for Responsible:
...items?expand=fields($select=Responsible)
You can read about how this works in the documentation for FieldValueSet.
As for returning the userPrincipalName, currently you can't control which value it returns (it's either LookupId or displayName).I recommend visiting the UserVoice and adding your suggestion.

Related

Programmatically adding tags to Data Catalog Custom entries

I am trying to attach tags to data catalog custom entries. I am trying to create a python function to perform data catalog operations i.e. create/delete custom entries, create/delete tag templates, attach tags to the fields of the created custom entries.
I was able to create a custom entry and a tag template using the datacatalog_v1 library, however I don't find a method or a rest API to attach the tags fields to the custom entry columns.
I am however able to complete via the GCP web UI console
You could see the next couple of examples on how to work with a data catalog REST API, and refer to the documentation that Google provides here.
Create an entry group
Before using any of the request data, make the following replacements:
project-id: Your GCP project ID
entryGroupId: The ID must begin with a letter or underscore, contain only English letters, numbers and underscores, and be at most
64 characters.
3.displayName: The textual name for the entry group.
HTTP method and URL:
POST https://datacatalog.googleapis.com/v1/projects/project-id/locations/us-central1/entryGroups?entryGroupId=entryGroupId
Request JSON body:
{
"displayName": "Entry Group display name"
}
Save the request body in a file called request.json, and execute the following command:
$cred = gcloud auth application-default print-access-token
$headers = #{ "Authorization" = "Bearer $cred" }
Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://datacatalog.googleapis.com/v1/projects/project-id/locations/us-central1/entryGroups?entryGroupId=entryGroupId" | Select-Object -Expand Content
You should receive a JSON response similar to the following:
{
"name": "projects/my_projectid/locations/us-central1/entryGroups/my_entry_group",
"displayName": "Entry Group display name",
"dataCatalogTimestamps": {
"createTime": "2019-10-19T16:35:50.135Z",
"updateTime": "2019-10-19T16:35:50.135Z"
}
}
You can structure your tags by topic using tag templates. For example:
A data governance tag with fields for: data governor, retention date, deletion date, PII (yes or no), data classification (public,
confidential, sensitive, regulatory)
A data quality tag with fields for: quality issues, update frequency, SLO information
A data usage tag with fields for: top users, top queries, average daily users

Finding a message across multiple folder trees with one call with microsoft-graph java sdk

In converting from an older bit of code that uses the EWS (ews-java-api v 2.0) SDK/API/Scope to Graph (microsoft-graph v5.4.0), I found that I could search (say by InternetMessageId) across multiple folder hierarchies at once in EWS with (simplifying how to get FolderId values a bit):
SearchFilter.SearchFilterCollection filter =
new SearchFilter.SearchFilterCollection(LogicalOperator.And);
filter.add(new SearchFilter.IsEqualTo(EmailMessageSchema.InternetMessageId, msgId));
List<FolderId> folders = Arrays.asList(new FolderId("AllItems"), new FolderId("Deletions"));
ItemView view = new ItemView(10);
ServiceResponseCollection<FindItemResponse<Item>> findResultsCollection =
service.findItems(searchFolders, filter, null, view, null, ReturnErrors);
With that EWS search whether my message of interest is in the Inbox, some user-created sub-folder, JunkEmail, DeletedItems, RecoverableItemsDeletions I find it by InternetMessageId in one go.
With Graph I issue two calls to be able to ensure the message does not exist
UserRequestBuilder u = GraphServiceClient
.builder()
.authenticationProvider(authenticationProvider)
.buildClient()
.users(user);
for (String folderTree : Arrays.asList("AllItems", "RecoverableItemsDeletions")) {
MessageCollectionPage mcp = u.mailFolders(folderTree)
.messages()
.buildRequest()
.filter("internetMessageId eq '" + msgId + "'")
.get();
Is there a way to search multiple trees in one go with Graph to be more like the EWS path that took a List?
Use List Messages endpoint to get the messages in the signed-in user's mailbox (including the Deleted Items and Clutter folders).
Depending on the page size and mailbox data, getting messages from a mailbox can incur multiple requests. The default page size is 10 messages. Use $top to customize the page size, within the range of 1 and 1000.
To improve the operation response time, use $select to specify the exact properties you need. Refer documentation here.
Java Code Snippet -
GraphServiceClient graphClient = GraphServiceClient.builder().authenticationProvider( authProvider ).buildClient();
MessageCollectionPage messages = graphClient.me().messages()
.buildRequest()
.select("sender,subject")
.get();

How to modify BoardColumn field of a Work Item using REST API

I have a customized Board with:
First default column "New" mapped to "New" state.
Second column "To do" also mapped to "New" state (After weekly reviewing new WI, team moves them in this column to avoid reviewing them next time).
In the TFS Board I can move a WI from the First Column to the second columun.
With the REST API when I read an existing WI, I got the right information for the BoardColumn field.
But when I used the REST API to modify BoardColumn it raises an exception.
I have the bypass rules permission.
$tfsTargetUri = "https://path to my collection/"
$tfsTargetProject = "MyProject"
$MyWI = 56 #use an existing Id
$mycredentials = Get-Credential
$workitem2 =
#(
#{op="test";path="/rev";value="1"},
#{op="add";path="/fields/System.BoardColumn";value="New"}
##{op="add";path="/fields/System.State";value="Active"}
)
$json2 = $workitem2 | ConvertTo-Json -Depth 100
$url2= $tfsTargetUri + $tfsTargetProject + '/_apis/wit/workitems/' + $MyWI +'?bypassRules=true&api-version=2.0'
$targetbug = Invoke-RestMethod -Uri $url2 -Method Patch -Credential $mycredentials -Body ([System.Text.Encoding]::UTF8.GetBytes($json2)) -ContentType 'application/json-patch+json'
When I try with BoardColumn in workitem2 it raises an exception.
When I modify the comment in workitem2 to change the State field, this is working.
Any idea?
The field System.BoardColumn is read only by design, is not a regular work item rule, so bypass = true can helps in this case. This is the reason why you can not update this field with the regular way.
According to new Microsoft Docs you provided (the relevant section added 3 days ago) there is a solution. You can update the field if you update another field value - if you get the work item and investigate the fields you will see this kind of field:
WEF_432678B52358ACDA34ASDA243489FD343_Kanban.Column
When you update this field to the Board Column State the work item will move to this Board Column.
Example how to extract this field from work item details:
$url = $collection/_apis/wit/workitems/$id?api-version=4.0
$workItem = Invoke-RestMethod -Uri $url -Method Get ...
$boardColumnField = $workItem.fields.PSObject.Properties.Name.Where({$_.Contains("Kanban")})[0]
# Now in the work item json use it: /fields/$boardColumnFied
Here are the settings that worked for me when using Postman:

How to search the group by the DisplayName using Microsoft Graph?

According to the document, I can list the Office 365 Groups by using the following Graph API:
GET https://graph.microsoft.com/v1.0/groups
I have a C# Web application, and there is a input for searching by the Group DisplayName. Any idea how to query groups based on the DisplayName?
I have tried the following URL: https://graph.microsoft.com/v1.0/groups?$search="displayName:Test" in the MS Graph Explorer which didn't work.
I get the following error.
{
"error": {
"code": "Request_UnsupportedQuery",
"message": "This query is not supported.",
"innerError": {
"request-id": "35d90412-03f3-44e7-a7a4-d33cee155101",
"date": "2018-10-25T05:32:53"
}
}
Any suggestion is welcomed.
Thanks in advance.
According to your description, I assume you want to search the Group by the DisplayName using the search parameters.
Based on this document, we can currently search only message and person collections. So we couldn't use the search parameter.
We can use the filter query parameter to search the Group by DisplayName. For example, we can search the groups whose displayName is start with 'Test',the request url like this:
https://graph.microsoft.com/v1.0/groups?$filter=startswith(displayName,'Test')
Here is C# code that I wrote to get a group using the DisplayName. This code requires a reference to the OfficeDevPnP.Core.
private static async Task<Group> GetGroupByName(string accessToken, string groupName)
{
var graphClient = GraphUtility.CreateGraphClient(accessToken);
var targetGroupCollection = await graphClient.Groups.Request()
.Filter($"startsWith(displayName,'{groupName}')")
.GetAsync();
var targetGroup = targetGroupCollection.ToList().Where(g => g.DisplayName == groupName).FirstOrDefault();
if (targetGroup != null)
return targetGroup;
return null;
}
UPDATE
I see that the answer has already been accepted, but I came across the same issue and found that this answer is out of date. For the next person, this is the update:
The 'search' functionality does work. Whether it was fixed along the way or always has, I am not sure.
'groups' support search,
both the v1 and beta api support search,
search only works on 'displayName' and 'description' fields,
searching on 'directory objects' require a special header: 'ConsistencyLevel: eventual'
Point number 4 is what tripped me up!
Your request would look like this:
https://graph.microsoft.com/v1.0/groups?$search="displayName:Test"
With the request header:
ConsistencyLevel: eventual
There is another catch: You can only specify the first 21 characters and the search always uses 'startsWith'. You're out of luck if you specify more than that: The search always fails.

java | Youtube API : Searching for channels related to a keyword

How can i retrieve a list of channels name ?
so for example :
( i'm searching for "abcde" ) so , if i type "ab" ,the link given below should give me the JSON with the channels name list :
ex.
-abc
-abbe
-abcd
-abcde
https://www.googleapis.com/youtube/v3/..../search=ab
i only found this https://www.googleapis.com/youtube/v3/channels?part=contentDetails&forUsername=USERNAMEUSER&key={API_KEY}
If you want to retreive all channel start with "ad" for example, you need to use the ressource search.list with the parameters:
part: snippet
q: "ad" //for example
type: channel
https://www.googleapis.com/youtube/v3/search?part=snippet&q=ad&type=channel&key={YOUR_API_KEY}
The result show you all the YouTube channel starting with "ad"

Resources