In my SharePoint site Document Library, I have a folder called OneDriveInventory and I have a few file inside.
I'm trying to access those file but it look like my Uri request is wrong so I would be really appreciated I can get any help or suggestion on how to fix this.
Invoke-WebRequest -Uri "https://graph.microsoft.com/v1.0/sites/$siteId/drives/$driveId/OneDriveInventory/$($filename)" -Method GET -OutFile $filePath -Headers $headers
I tried to reproduce the same in my environment and got below results:
I have one SharePoint document library in which I created folder named OneDriveInventory and added files like below:
You can make use of below Graph API call to access file in the above folder:
GET https://graph.microsoft.com/v1.0/sites/<siteID>/drives/<driveID>/root:/OneDriveInventory:/children/<filename>
When I ran the above query in Graph Explorer, I got results successfully like below:
To get the same results from PowerShell, I registered one Azure AD application and added API permissions like below:
Now I generated access token using below PowerShell script:
$tenantId = <tenantID>
$applicationId = <appID>
$secret= <secret>
$param = #{
Uri = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token";
Method = 'Post';
Body = #{
grant_type = 'client_credentials';
scope = 'https://graph.microsoft.com/.default';
client_id = $applicationId;
client_secret = $secret
}
}
$result = Invoke-RestMethod #param
$token = $result.access_token
Response:
To access file from folder, I used below PowerShell script:
$siteID = "3b23b598-f5e4-461f-b038-xxxxxx"
$driveID = "xxxxxxxxxxxxxxxxxxx"
$filename = "sridevi.txt"
$headers=#{}
$headers.Add("Content-Type", "text/plain")
$headers.Add("Authorization", "Bearer $token")
$response=Invoke-WebRequest -Uri "https://graph.microsoft.com/v1.0/sites/$siteID/drives/$driveID/root:/OneDriveInventory:/children/$($filename)" -Method GET -OutFile $filePath -Headers $headers
Response:
When I ran $response.Content, I got full response like below:
Related
Am currently creating a PowerShell script to retrieve a specific SharePoint online site using Microsoft graph api. The goal is, once i retrieve the site, then i can grab the siteid. My script fails on the api call. Have tried different search and filter combination, but it's not working. All of my api calls just retrieves all the sites. I got all required permissions assigned to the app registration.
Below is the entire script.
$siteUrl = "https://bernardcomms.sharepoint.com/sites/Project1"
$tenantId = ""
$clientId = ""
$clientSecret = ""
# Get an access token for the Microsoft Graph API
$tokenAuthUri = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"
$tokenRequestBody = #{
grant_type = "client_credentials"
client_id = $clientId
client_secret = $clientSecret
scope = "https://graph.microsoft.com/.default"
}
$tokenResponse = Invoke-RestMethod -Method Post -Uri $tokenAuthUri -Body $tokenRequestBody
$accessToken = $tokenResponse.access_token
# Get the ID of the SharePoint site
$requesturi = "https://graph.microsoft.com/v1.0/sites?$search=$siteUrl"
$siteIdResponse = Invoke-RestMethod -Method Get -Uri $requesturi -Headers #{Authorization=("bearer {0}" -f $accessToken)}
$siteId = $siteIdResponse.value.id
$siteId
Have tried to use below calls but it just returns all the sites.
$requesturi = "https://graph.microsoft.com/v1.0/sites?$search=weburl eq '$siteUrl'"
$requesturi = "https://graph.microsoft.com/v1.0/sites?$filter=weburl eq '$siteUrl'"
How can I retrieve a site that has a matching specific siteurl.
permissions assigned.
I agree with #Cpt.Whale, you need to change your graph query to https://graph.microsoft.com/v1.0/sites/bernardcomms.sharepoint.com:/sites/Project1
I tried to reproduce the same in my environment and got below results:
I registered one Azure AD application and granted same API permissions like below:
I have one SharePoint site named sritestsite like below:
When I ran below PowerShell script by making few changes, I got siteID successfully like below:
$hostName = "mytenant.sharepoint.com"
$siteName = "sitename"
$tenantId = <tenantID>
$clientId = <appID>
$clientSecret = <secret>
# Get an access token for the Microsoft Graph API
$tokenAuthUri = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token"
$tokenRequestBody = #{
grant_type = "client_credentials"
client_id = $clientId
client_secret = $clientSecret
scope = "https://graph.microsoft.com/.default"
}
$tokenResponse = Invoke-RestMethod -Method Post -Uri $tokenAuthUri -Body $tokenRequestBody
$accessToken = $tokenResponse.access_token
# Get the ID of the SharePoint site
$requesturi = "https://graph.microsoft.com/v1.0/sites/$hostName`:/sites/$siteName"
$siteIdResponse = Invoke-RestMethod -Method Get -Uri $requesturi -Headers #{Authorization=("bearer {0}" -f $accessToken)}
$siteId = $siteIdResponse.id
$siteId
Response:
To get full response, you can run $siteIdResponse like below:
I'm trying to get all SharePoint Online sites' name and url via PowerShell using MS Graph API, but it's not seem to be working. That's all I get from the request:
#{#odata.context=https://graph.microsoft.com/v1.0/$metadata#sites; value=System.Object[]}
The application I use have all the needed Application type API permissions (Sites.Read, Sites.ReadWrite.All) with admin consent.
Do you have any idea why my script not working?
The code:
$TenantID = 'xxxxxxxxx.ONMICROSOFT.COM'
$ApplicationId = "xxxxx-xxxxxx-xxxx-xxxx"
$ApplicationSecret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
$body = #{
'resource' = 'https://graph.microsoft.com'
'client_id' = $ApplicationId
'client_secret' = $ApplicationSecret
'grant_type' = "client_credentials"
'scope' = "openid"
}
$ClientToken = Invoke-RestMethod -Method post -Uri "https://login.microsoftonline.com/$($tenantid)/oauth2/token" -Body $body -ErrorAction Stop
$headers = #{ "Authorization" = "Bearer $($ClientToken.access_token)" }
$AllSites = Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/sites?search=*" -Headers $headers -Method Get
Write-Host $AllSites
I've also tried these URIs:
https://graph.microsoft.com/v1.0/sites?search=*
https://graph.microsoft.com/v1.0/sites
https://graph.microsoft.com/v1.0/sites$select=siteCollection,webUrl&$filter=siteCollection/root%20ne%20null
The Write-Host cmdlet's primary purpose is to produce
for-(host)-display-only output, such as printing colored text like
when prompting the user for input in conjunction with Read-Host.
Write-Host uses the ToString() method to write the output. By
contrast, to output data to the pipeline, use Write-Output or implicit
output.
reference
This mean that your output is transformed for display purposes. Where you see System.Object[], there is actually data in there just waiting for you.
Based on your current results, your query look good.
Just do not use Write-Host and dig into the object as needed.
To get the site names, just use $AllSites.Value.Name
$AllSites = Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/sites?search=*" -Headers $headers -Method Get
# Return site names
$AllSites.Value.Name
If you need to get additional information from each return you can loop into them, like this to do whatever you need. Here is a custom display of the site name along with an arbitrary index and the associated URL
$index = 0
# Will display results like
# 0: SiteName - www.contoso.sharepoint.com/SiteUrl
foreach ($Site in $AllSites.Value) {
Write-Host "$($index.ToString().PadRight(3,' ')): $($Site.Name) - " -NoNewline
Write-Host $site.webUrl -ForegroundColor Cyan
$index += 1
}
Also, here is an additional reference when working with Azure Graph API that will confirm your requests are working as expected: https://developer.microsoft.com/en-us/graph/graph-explorer
I'm trying to get a subset of machines from Microsoft Defender ATP through API calls using OData $filter queries following Microsoft's instructions (https://learn.microsoft.com/en-us/windows/security/threat-protection/microsoft-defender-atp/exposed-apis-odata-samples) but regardless of what I do, I'm getting the same full set of machines which limits at 10,000.
So, some reason my following codes is not working as it should. What am I doing wrong? Also, how do I get more than 10,000 machines?
I removed tenantId, appId, and appSecret variables from the code below.
UPDATE:
I noticed that when I check the value of $machinesUrl2 variable in the PowerShell ISE after running the script, it shows that "$filter" is missing from the URI. The following is the output of variable $machinesUrl2:
https://api.securitycenter.windows.com/api/machines?=healthStatus+eq+'Inactive'
What is causing the drop of "$filter"? is this normal behavior?
Thanks,
$resourceAppIdUri = 'https://securitycenter.onmicrosoft.com/windowsatpservice'
$oAuthUri = "https://login.windows.net/$TenantId/oauth2/token"
$authBody = [Ordered] #{
resource = "$resourceAppIdUri"
client_id = "$appId"
client_secret = "$appSecret"
grant_type = 'client_credentials'
}
$authResponse = Invoke-RestMethod -Method Post -Uri $oAuthUri -Body $authBody -ErrorAction Stop
$aadToken = $authResponse.access_token
$machinesUrl2 = "https://api.securitycenter.windows.com/api/machines?$filter=healthStatus+eq+'Inactive'"
$headers = #{
'Content-Type' = 'application/json'
Accept = 'application/json'
Authorization = "Bearer $aadToken"
}
$machinesResponse = Invoke-WebRequest -Method Get -Uri $machinesUrl2 -Headers $headers -ErrorAction Stop
$machines = ($machinesResponse | ConvertFrom-Json).value
I found the answer while trying to figure out why the $filter was getting dropped out of the query string.
It needed to have a back-tick character (`) added to in front of the "$filter".
https://api.securitycenter.windows.com/api/machines?`$filter=healthStatus+eq+'Inactive'
After adding this character to the query string, the code on this Microsoft documentation started to work.
I am trying to set the value of retainedByRelease property of a build in one of my build pipelines by calling Azure Rest API through PowerShell. I am getting "page not found" error in the terminal. I suspect I am preparing the URL wrong but not sure where. Please help.
To figure out the URL, I got the area id from the below link for Build (which is 5d6898bb-45ec-463f-95f9-54d49c71752e).
https://learn.microsoft.com/en-us/azure/devops/extend/develop/work-with-urls?view=azure-devops&tabs=http#resource-area-ids-reference
Got the personalized token from VSO.
Below is what the script looks like (masked the token and the build id):
$orgURL = "https://dev.azure.com"
$personalToken = "*******"
$token = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($personalToken)"))
$header = #{authorization="Bearer $token"}
$areaId = "5d6898bb-45ec-463f-95f9-54d49c71752e"
$orgResourceAreasUrl = [string]::Format("{0}/_apis/resourceAreas/{1}?api-version=5.0-preview.1",$orgURL,$areaId)
$results = Invoke-RestMethod -Uri $orgResourceAreasUrl -Headers $header
$basrUrl = $results.locationUrl
Invoke-RestMethod -Uri ($basrUrl + '_apis/build/builds/<someBuildId>?api-version=3.2') -Method Patch -Body (ConvertTo-Json #{"retainedByRelease"='false'}) -Headers $header -ContentType "application/json" | Out-Null
I am getting the error on the last line on Invoke-RestMethod call.
I am trying this because the build pipeline underneath is throwing some compliance error and I need to remove that pipeline and I am not able to delete it as this build is being retained by the release.
P.S, I have already checked the below links.
https://developercommunity.visualstudio.com/content/problem/442784/one-or-more-builds-associated-with-the-requested-p.html - looks like the permanent fix is not in place yet
https://almguide.net/2018/12/13/build-blocked-by-release/
-Uri ($basrUrl + 'https://tfsprodea1.visualstudio.com/')
The error caused by this incorrect url constructed. You can use Write-Host $orgResourceAreasUrl to print out the url you constructed previous, and you will see that the values of $results.locationUrl is https://tfsprodea1.visualstudio.com/ instead of https://dev.azure.com/{your org name}/. So, in fact, at the last line of script, the value of url you constructed is https://tfsprodea1.visualstudio.com/_apis/build/builds/<someBuildId>?api-version=3.2. This is not a correct url which can be identified by Azure Devops. The correct url should be https://dev.azure.com/{org name}/_apis/build/builds/{build id}?api-version=3.2
The root cause of this error is that the value you specified to orgURL is not correct. For correct the error you received, you should change the value of $orgURL and specify it as the below shown:
$orgURL = "https://dev.azure.com/{your org name}"
Only this, you can get the correct value of locationUrl.
In addition, at the line of script, the url you constructed is
https://dev.azure.com/{org name}/_apis/build/builds/{build id}?api-version=3.2
This is a definition message which is organization level, you could not UPDATE it with token. Or you will receive the message The project with id 'No project was specified.' does not exist, or you do not have permission to access it..
If you still want to update the value of retainedByRelease, please construct the url as
https://dev.azure.com/{org name}/{project name}/_apis/build/builds/{build id}?api-version=3.2
And this is a project level info which can be updated with token.
So, based on your script, I made some change:
[String]$project = "$env:SYSTEM_TEAMPROJECT"
$orgURL = "https://dev.azure.com/{your org name}"
$header = #{
Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
}
$areaId = "5d6898bb-45ec-463f-95f9-54d49c71752e"
$orgResourceAreasUrl = [string]::Format("{0}/_apis/resourceAreas/{1}?api-version=5.0-preview.1",$orgURL ,$areaId)
$results = Invoke-RestMethod -Uri $orgResourceAreasUrl -Headers $header
$basrUrl = $results.locationUrl
Invoke-RestMethod -Uri ($basrUrl + $project + '/_apis/build/builds/{build id }?api-version=3.2') -Method Patch -Body (ConvertTo-Json #{"retainedByRelease"='false'}) -Headers $header -ContentType "application/json" | Out-Null
Note: Enable the below checkbox first so that you can use the System.AccessToken in your script.
So we switched to Bitbucket recently - Love the different pricing model / the branch and repo permissions. But, I REALLY miss the Releases feature in GitHub.
BB does however have a "Downloads" section that we can upload recent binaries to. But... It isnt exposed via their API.
I found a nifty script that uses cURL, but I wanted to do this in PowerShell so I dont need any special programs (we use AppVeyor as our CI Server, no cURL).
I have this mostly working - The process is:
Load Signin page to get CSRF token - working
Sign in, redirecting to downloads page - working
Upload file - failing
My code is here
I have isolated the problem to the form data. Here is what it looks like in fiddler when I just do the upload myself:
But when I use Powershell I cannot get it to populate the "WebForms" tab of the request. I've tried using the -InFile and specifying the file to upload, but Bitbucket requires the other shown parameters as well.
How do I specify a series of "Form Fields" to include in the request with Powershell?
EDIT
Adding code here, even though it makes this messy.
$baseUri = "https://bitbucket.org"
$teamName = "xxxxxxxxx"
$projectName = "xxxxxxxxxxxxxxx"
$page = "/$teamName/$projectName/downloads"
$uri = "https://bitbucket.org/account/signin/"
$username = "xxxxxxxxxxxxxxxx"
$password = "xxxxxxxxxxxxxxxx"
$headers = #{
"referer" = "$uri"
}
$json = #"
{
"username":"$username",
"password":"$password",
"submit":"",
"next":"$page",
"csrfmiddlewaretoken":""
}
"#
$formData = #"
{
"token":"",
"csrfmiddlewaretoken":""
}
"#
$body = $json | ConvertFrom-Json
$formData2 = $formData | ConvertFrom-Json
#Load the page once to get the csrf token
Invoke-RestMethod -Uri $uri -SessionVariable mySession -Method Get -OutFile test2.html
#Parse the token
$body.csrfmiddlewaretoken = $mySession.Cookies.GetCookies("https://bitbucket.org")[0].Value
$formData2.csrfmiddlewaretoken = $mySession.Cookies.GetCookies("https://bitbucket.org")[0].Value
#Load the token into the object
$json = $body | ConvertTo-Json
$formData = $formData2 | ConvertTo-Json
#build the uri data needed by bb
$uriData = "username=" + $body.username + "&password=" + $body.password + "&submit=&next=" + $body.next + "&csrfmiddlewaretoken=" + $body.csrfmiddlewaretoken
#Sign into BB now
Invoke-RestMethod -Uri "https://bitbucket.org/account/signin/" -WebSession $mySession -Body $uriData -Method Post -OutFile test.html -Headers $headers
#Update referer to the downloads page
$headers.referer = $baseuri + $page
$fulluri = $baseuri + $page
#Upload the file
Invoke-RestMethod -Uri "$fulluri" -Method Post -OutFile test3.html -WebSession $mySession -Headers $headers -Body $formData -ContentType "multipart/form-data"