Is it possible to get full path to a OneDrive item? - microsoft-graph-api

I'm using the MS Graph SDK in a C# project to search through people's OneDrives for specific terms in files and folders. When I find one, I've not found a way to get the full path for a DriveItem?
Not the URL path, but the file system path where the owning user stores the file locally.
Is this possible?

When you request the metadata for a drive item you receive for example:
{
"#microsoft.graph.downloadUrl": "https://m365x214355-my.sharepoint.com/personal/meganb_m365x214355_onmicrosoft_com/_layouts/15/download.aspx?UniqueId=c8b43b37-bc76-4352-af27-5a8e9f1bbfeb&Translate=false&tempauth=eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJhdWQiOiIwMDAwMDAwMy0wMDAwLTBmZjEtY2UwMC0wMDAwMDAwMDAwMDAvbTM2NXgyMTQzNTUtbXkuc2hhcmVwb2ludC5jb21AZGNkMjE5ZGQtYmM2OC00YjliLWJmMGItNGEzM2E3OTZiZTM1IiwiaXNzIjoiMDAwMDAwMDMtMDAwMC0wZmYxLWNlMDAtMDAwMDAwMDAwMDAwIiwibmJmIjoiMTUzMzg5NzE3MiIsImV4cCI6IjE1MzM5MDA3NzIiLCJlbmRwb2ludHVybCI6IitjMlZ4YU9UY2hCSEhmK3hyNlhrMExtd0pRMEhQR0hYMmlKaTBMRldhTHM9IiwiZW5kcG9pbnR1cmxMZW5ndGgiOiIxNjkiLCJpc2xvb3BiYWNrIjoiVHJ1ZSIsImNpZCI6Ik16VTVOVFkyWVRjdFlqazVOeTAwWlRsa0xUZ3hNV1V0TlRNMU5UZGhaRGc0WkdVeSIsInZlciI6Imhhc2hlZHByb29mdG9rZW4iLCJzaXRlaWQiOiJaRGd5TXpFeVpqa3RZakl6WWkwMFkySmpMVGsxWkRVdE0yVXdaRGswWlRZNFl6RmwiLCJhcHBfZGlzcGxheW5hbWUiOiJhcGlzYW5kYm94cHJveHkiLCJhcHBpZCI6IjAwOTFlNTllLTE3ZTgtNDdmMC1hNDUwLTQ0M2Q0ZGQzYTAwNiIsInRpZCI6ImRjZDIxOWRkLWJjNjgtNGI5Yi1iZjBiLTRhMzNhNzk2YmUzNSIsInVwbiI6Im1lZ2FuYkBtMzY1eDIxNDM1NS5vbm1pY3Jvc29mdC5jb20iLCJwdWlkIjoiMTAwM0JGRkRBMzgxMzFBRiIsInNjcCI6ImFsbHNpdGVzLnJlYWQgbXlmaWxlcy5yZWFkIGdyb3VwLnJlYWQgbXlmaWxlcy5yZWFkIGFsbHNpdGVzLnJlYWQgYWxsc2l0ZXMucmVhZCBteWZpbGVzLnJlYWQgYWxscHJvZmlsZXMucmVhZCBhbGxwcm9maWxlcy5yZWFkIiwidHQiOiIyIiwidXNlUGVyc2lzdGVudENvb2tpZSI6bnVsbH0.eWQzcTFxNmhBb0txNFNnZzQyNlIyU2gzaUQwSGJxbC9abWRlVVZ3OGUwMD0&ApiVersion=2.0",
"createdDateTime": "2017-08-07T16:17:44Z",
"eTag": "\"{C8B43B37-BC76-4352-AF27-5A8E9F1BBFEB},2\"",
"id": "01BYE5RZZXHO2MQ5V4KJB26J22R2PRXP7L",
"lastModifiedDateTime": "2017-08-07T16:17:44Z",
"name": "Camera Customer Analysis.xlsx",
"webUrl": "https://m365x214355-my.sharepoint.com/personal/meganb_m365x214355_onmicrosoft_com/_layouts/15/Doc.aspx?sourcedoc=%7BC8B43B37-BC76-4352-AF27-5A8E9F1BBFEB%7D&file=Camera%20Customer%20Analysis.xlsx&action=default&mobileredirect=true",
"cTag": "\"c:{C8B43B37-BC76-4352-AF27-5A8E9F1BBFEB},1\"",
"size": 2675045,
"createdBy": {
"user": {
"email": "MeganB#M365x214355.onmicrosoft.com",
"id": "48d31887-5fad-4d73-a9f5-3c356e68a038",
"displayName": "Megan Bowen"
}
},
"lastModifiedBy": {
"user": {
"email": "MeganB#M365x214355.onmicrosoft.com",
"id": "48d31887-5fad-4d73-a9f5-3c356e68a038",
"displayName": "Megan Bowen"
}
},
"parentReference": {
"driveId": "b!-RIj2DuyvEyV1T4NlOaMHk8XkS_I8MdFlUCq1BlcjgmhRfAj3-Z8RY2VpuvV_tpd",
"driveType": "business",
"id": "01BYE5RZ6TAJHXA5GMWZB2HDLD7SNEXFFU",
"path": "/drive/root:/CR-227 Project"
},
"file": {
"mimeType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"hashes": {
"quickXorHash": "qz9+NLaGwZCFBcd9gH+HCNUVcn8="
}
},
"fileSystemInfo": {
"createdDateTime": "2017-08-07T16:17:44Z",
"lastModifiedDateTime": "2017-08-07T16:17:44Z"
}
}
As you can see it contains a parentReference which contains the path
To get the full path, substring the path starting at the first : and append the name.
In the above example it would give: /CR-227 Project/Camera Customer Analysis.xlsx
Doc reference
However, getting the local path where the user stored the file locally is not stored by Microsoft. But you can reproduce it because the OneDrive file structure will be the same as the local one.

Based on my test, we can't use the Graph API to get the root directory of the OneDrive local file system. We can only get the relative path of the OneDrive item.
My test configuration: local storage directory: C:/onedrive. The file is stored in “C:/onedrive/Test Floder/”. We can only get the “path /drive/root:Test”.
enter image description here
The repro steps:
We can try the following API to get the relative path for the user's OneDrive settings first:
https://graph.microsoft.com/v1.0/me/drive/items/{item-id}/children .
Then, you can stitch the file system path set by the user with the relative path obtained from the API.
We can set different file system paths on the local system for OneDrive. You can refer to this article to set the local storage location for OneDrive.

Related

Graph REST API - Search inside DriveItem not working for non-mainstream file extensions

I've been trying to search within a specific DriveItem folder but I've been having some troubles. First of all, despite the API stating that "You can search within a folder hierarchy, a whole drive, or files shared with the current user.", I haven't found any documentation supporting this. I have found this stackoverflow reply that describes how to do it. Unfortunately, it doesn't to be working very well.
Since I don't know how sensitive IDs are, I'll be redacting them in my examples.
https://graph.microsoft.com/v1.0/me/drive/items/<id_parent_folder>/children?select=name
This request returns all files inside the folder I want to search and it does list everything inside the folder. The response is something like:
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('<id_user>')/drive/items('<id_parent_folder>')/children(name)",
"value": [
{
"#odata.etag": "\"{redacted1},1\"",
"name": "automation_csv.csv"
},
{
"#odata.etag": "\"{redacted2},1\"",
"name": "HOSPITAIS_PT.cpg"
},
{
"#odata.etag": "\"{redacted3},1\"",
"name": "HOSPITAIS_PT.dbf"
},
{
"#odata.etag": "\"{redacted4},1\"",
"name": "HOSPITAIS_PT.prj"
},
{
"#odata.etag": "\"{redacted5},1\"",
"name": "HOSPITAIS_PT.qpj"
},
{
"#odata.etag": "\"{redacted6},1\"",
"name": "HOSPITAIS_PT.shp"
},
{
"#odata.etag": "\"{redacted7},1\"",
"name": "HOSPITAIS_PT.shx"
}
]
}
However, when searching inside the folder I only get the CSV file....
https://graph.microsoft.com/v1.0/me/drive/items/<id_parent_folder>/search(q='')?select=name
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#Collection(driveItem)",
"value": [
{
"#odata.type": "#microsoft.graph.driveItem",
"name": "<name_parent_folder>"
},
{
"#odata.type": "#microsoft.graph.driveItem",
"name": "automation_csv.csv"
}
]
}
Searching for any other file name produces no results.
Is this a bug or a feature? Is there another endpoint that allows me to search all files inside a folder?
EDIT: changed the "beta" endpoint to "v1.0", though they produce the same results. Just don't want to create the assumption that it only happens in the beta endpoint.
Use the Microsoft Query API to search instead of using q search parameter.
See https://learn.microsoft.com/en-us/graph/api/resources/search-api-overview?view=graph-rest-beta

How can I parse email addresses from Sharepoint DriveItem permissions?

So I've been trying to get email addresses of people that have access to certain files in a Sharepoint document library of a site through the use of the Microsoft Graph API. Below is an example of how my permission object looks like, which is retrieved from https://graph.microsoft.com/v1.0/sites/<site id>/drives/<drive id>/items/<item id>/permissions.
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#sites('...')/drives('...')/items('...')/permissions",
"value": [
{
"id": "...",
"roles": ["owner"],
"grantedTo": { "user": { "displayName": "testsite - Eigenaars" } },
"inheritedFrom": {}
},
{
"id": "...",
"roles": ["read"],
"grantedTo": { "user": {"displayName": "testsite - Bezoekers"} },
"inheritedFrom": {}
},
{
"id": "...",
"roles": ["write"],
"grantedTo": { "user": { "displayName": "testsite - Leden" } },
"inheritedFrom": {}
},
{
"id": "...",
"roles": [
"write"
],
"grantedToV2": {
"siteGroup": {
"displayName": "Developers",
"id": "120",
"loginName": "Developers"
}
},
"grantedTo": {
"user": {
"displayName": "Developers"
}
},
"inheritedFrom": {}
},
{
"id": "...",
"roles": ["owner"],
"grantedTo": {
"user": {
"email": "testsite#mysharepoint",
"id": "uuid",
"displayName": "testsite - Eigenaars"
}
},
"inheritedFrom": {}
}
]
}
I assume the testsite in the displayName property is a group name (probably the group that belongs to the site the file resides in), but I have seen cases where I can't find this group name in the groups retrieved from the /groups endpoint in the Graph API.
You can also see the group Developers, which I haven't managed to find in the full group list retrieved from /groups.
The documentation around this is quite vague and unclear to me. Somewhere I read that this lack of data could be due to authentication scopes, but I have "god mode" administrator rights in this Sharepoint environment, so that would seem strange to me.
My main goal is to be able to get all users that have access to a specific file.
Thanks in advance!
1. I assume the testsite in the displayName property is a group name, but I have seen cases where I can't find this group name in the groups retrieved from the /groups endpoint in the Graph API.
This is because as per Drive Item Permission >> Identity Set >> Identity resource type Quoting
The identity's display name. Note that this may not always be available or up to date. For example, if a user changes their display name, the API may show the new value in a future response, but the items associated with the user won't show up as having changed when using
This can explain why sometimes you don't see the group name in your groups.
I suggest you use the id.
2. My main goal is to be able to get all users that have access to a specific file.
Do you have any users that appear on the Has Access section of the drive item on sharepoint? For users you should be able to get permissions and use the ids to Get directoryObject using the id values from grantedToIdentitiesV2 or grantedToV2 which will return odate type.
GET https://graph.microsoft.com/v1.0/directoryObjects/{id}?$select=id
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#directoryObjects(id)/$entity",
"#odata.type": "#microsoft.graph.group or user or application",
"id": "id"
}
For groups, the users would be the members of the group.

How to Create Empty folders under Microsoft Teams --> Channel using Graph API?

I am using Graph API for creation of Teams and then channels. But after the creation of a channel I want to add some empty folders inside that. How can Achieve this using graph API ?
Team -> Channel -> File -> Folders
You need to get the metadata for the location where the folders or files of a channel are stored.
GET /teams/{id}/channels/{id}/filesFolder
The response returns driveItem resource with driveId and driveItem's id.
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#teams('32e3b156-66b2-4135-9aeb-73295a35a55b')/channels('19%3Af253e46c035b42308e9a4a22a87037af%40thread.skype')/filesFolder/$entity",
"id": "01H7CFEKENJSSIUHGADZBKODARINQC5JMD",
"createdDateTime": "0001-01-01T00:00:00Z",
"lastModifiedDateTime": "2020-01-23T18:47:13Z",
"name": "Documentation Planning",
"webUrl": "xxx",
"size": 2374080,
"parentReference": {
"driveId": "b!2SInBlQrN0K8-GXMy9qNsPtI5ScW8C5IlZtycoy6ZpJZRRtgE4qVTrE8wrvL0-hd",
"driveType": "documentLibrary"
},
...
}
Then you can create a new folder by calling the endpoint:
POST /drives/{driveId}/items/{id}/children
Get files folder
Create folder

Get all the files in others Onedrive in MS Graph

I am trying to list all files in another user's OneDrive.
I am calling GET /users/{user-id}/drive/items/{item-id}/children but my problem is that I do not know how to get the {item-id}.
I tried using https://graph.microsoft.com/v1.0/users/{userid}/drives but it is not showing any item ids.
Subsequently, once I get the id, I will use the copy command POST /users/{userId}/drive/items/{itemId}/copy to copy items.
If you do not know the ID or Path for the DriveItem, you'll need to start at the root of the Drive and walk the folder structure until your find the file(s) you're looking for.
Your first call would be to /users/{id|userPrincipalName}/drive/root/children?$select=id,name,folder,file. This will list the children's id, name, and either the folder or file data (depending on the item type) from the root folder:
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('id')/drive/root/children(id,name,folder,file)",
"value": [
{
"#odata.etag": "\"{etag},1\"",
"id": "folderId",
"name": "My Folder",
"folder": {
"childCount": 10
}
},
{
"#odata.etag": "\"{etag},1\"",
"id": "fileId",
"name": "filename.ext",
"file": {
"mimeType": "type",
"hashes": {
"quickXorHash": "hash"
}
}
}
]
}
You then execute the same call against each of the folders to get their children, repeating the pattern until your find the file you're looking for:
/users/{id|userPrincipalName}/drive/items/{folderId}/children?$select=id,name,folder,file`
Alternatively, you could simply search for the file using /users/{id|userPrincipalName}/drive/root/search(q='{search-text}').
You probably need to query root to get childIDs for files/folders
GET https://graph.microsoft.com/v1.0/users/{user-id}/drive/root/children

OneDrive. MS Graph API. Move file to root of drive fails with "One of the provided arguments is not acceptable"

I have the app that uses MS graph API for onedrive .
When i try to move a file to root of a drive from some folder i have an error "One of the provided arguments is not acceptable".
But same code works fine for "individual" onedrive accounts, problem is only for OneDrive for business accounts.
Also, move to any other folder works fine.
I am sending PATCH request o move a file.
For free onedrive the request body looks like
(
[parentReference] =>
(
[path] => //drives/68XXXXX7f7f7d7c/root
)
)
this works. but same code for oneDrive for business fails
(
[parentReference] =>
(
[path] => //drives/b!-0dIs3JX..TRUNCATED...0_oR2A...L0PY/root
)
)
This gives error "One of the provided arguments is not acceptable"
What can this be? Any ideas?
I follow the docs here https://learn.microsoft.com/en-us/graph/api/driveitem-move?view=graph-rest-1.0
This issue is noted in the documentation:
Note: When moving items to the root of a drive your app cannot use the "id:" "root" syntax. Your app needs to provide the actual ID of the root folder for the parent reference.
To retrieve the actual id, you need to retrieve the id from the root object:
/drives/{drive-id}/root
This will return something along the lines of this:
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#users('48d31887-5fad-4d73-a9f5-3c356e68a038')/drive/root/$entity",
"createdDateTime": "2017-07-27T02:41:36Z",
"id": "01BYE5RZ56Y2GOVW7725BZO354PWSELRRZ",
"lastModifiedDateTime": "2019-01-18T03:41:15Z",
"name": "root",
"webUrl": "https://m365x214355-my.sharepoint.com/personal/meganb_m365x214355_onmicrosoft_com/Documents",
"size": 106330475,
"parentReference": {
"driveId": "b!-RIj2DuyvEyV1T4NlOaMHk8XkS_I8MdFlUCq1BlcjgmhRfAj3-Z8RY2VpuvV_tpd",
"driveType": "business"
},
"fileSystemInfo": {
"createdDateTime": "2017-07-27T02:41:36Z",
"lastModifiedDateTime": "2019-01-18T03:41:15Z"
},
"folder": {
"childCount": 38
},
"root": {}
}
Using the above example, when moving the file, your path would be:
/drives/b!-RIj2DuyvEyV1T4NlOaMHk8XkS_I8MdFlUCq1BlcjgmhRfAj3-Z8RY2VpuvV_tpd/01BYE5RZ56Y2GOVW7725BZO354PWSELRRZ

Resources