Get programmatically User Roles and Permissions in SSRS 2008 - security

I use SSRS 2008 on Windows 2008 R2.
How can I get the user list of roles and permissions (Reports Manager Roles such as Browser, Content Manager, etc) using Powershell or C# (programmatically)?
Any suggestions ?
Notes:
"Folder Settings" area where you can specify roles for a user - "Content Manager," "Publisher," "Browser," "Report Builder," and "My Reports"
SSRS has 2 security/role sections available in the web GUI: Folder Settings and Site Settings.

I try with my script powershell.
References: http://www.bi-rootdata.com/2015/03/list-ssrs-items-permissions-using.html by Anup Agrawal comment
Usage:
$ScriptDirectory = Split-Path $MyInvocation.MyCommand.Path
Clear-Host
Write-Host $ScriptDirectory
Write-Host $env:COMPUTERNAME -ForegroundColor Yellow
Write-Host $env:USERNAME -ForegroundColor Yellow
$ReportServerUri = 'http://localhost/ReportServer/ReportService2005.asmx'
$InheritParent = $true
$SourceFolderPath = '/'
$outSSRSSecurity=#()
$Proxy = New-WebServiceProxy -Uri $ReportServerUri -Namespace SSRS.ReportingService2005 -UseDefaultCredential
$items = $Proxy.ListChildren($sourceFolderPath, $true)|Select-Object Type, Path, Name|Where-Object {$_.type -eq "Folder"};
foreach($item in $items)
{
#Write-Host $item
if ($item.Name -ne "TestsCustomCDR")
{
#continue;
}
Write-Host $item.Path -ForegroundColor Yellow
Write-Host $item.Name -ForegroundColor Green
Add-Member -InputObject $item -MemberType NoteProperty -Name PolicyGroupUserName -Value '';
foreach($policy in $Proxy.GetPolicies($item.path, [ref]$InheritParent))
{
Write-Host $policy.GroupUserName
$objtemp=$item.PsObject.Copy();
$objtemp.PolicyGroupUserName=$policy.GroupUserName;
$outSSRSSecurity += $objtemp;
$objtemp.reset;
}
}
$outSSRSSecurity|Export-csv SSRSSecurityOutput.csv -NoTypeInformation;

Related

How to add resource group as one factor to filter the output

<#
NAME
AzureSubscriptionRBACAudit.ps1
SYNOPSIS
Gathers Azure Role Based Access Control Data for Audit Purposes.
DESCRIPTION
Gathers Azure Role Based Access Control Data for Audit Purposes. The script will prompt the user to
select a subscription to run the audit against. The user is only presented the scriptions currently
available to the users credentials.
OUTPUTS
Outputs a CSV file in the same directory that the script is located in. The CSV file will have the
name of the subscription in its title followed by "Azure RBAC Audit.csv"
#>
Functions
Function Login {
<#
.SYNOPSIS
Runs the Azure Login Command
#>
$needLogin = $true
Try {
$content = Get-AzContext
if ($content) {
$needLogin = ([string]::IsNullOrEmpty($content.Account))
}
}
Catch {
if ($_ -like "*Login-AzAccount to login*") {
$needLogin = $true
}
else {
throw
}
}
if ($needLogin) {
#Login-AzAccount
Select-Azure
}
}
Function Select-Azure{
<#
.SYNOPSIS
Provides a list of Azure Environments for the user to select from.
AzureGov, AzureCloud, etc.
#>
Clear-Host
$ErrorActionPreference = 'SilentlyContinue'
$Menu = 0
$AzEnvironment = #(Get-AzEnvironment |select-object Name)
Write-Host "Please select the Azure Environment you want to use:" -ForegroundColor Green;
ForEach-Object {Write-Host ""}
$AzEnvironment | ForEach-Object {Write-Host "[$($Menu)]" -ForegroundColor Cyan -NoNewline ; Write-host ". $($_.Name)"; $Menu++; }
ForEach-Object {Write-Host ""}
ForEach-Object {Write-Host "[Q]" -ForegroundColor Red -NoNewline ; Write-host ". To quit."}
ForEach-Object {Write-Host ""}
$selection = Read-Host "Please select the Azure Environment Number - Valid numbers are 0 - $($AzEnvironment.count -1) or Q to quit"
If ($selection -eq 'Q') {
Clear-Host
Exit
}
If ($AzEnvironment.item($selection) -ne $null)
{ Connect-AzAccount -EnvironmentName $AzEnvironment.item($selection).Name -ErrorAction Stop}
}
Function Select-Subs {
<#
.SYNOPSIS
Provides a list of subscriptions for the user to select from.
#>
Clear-Host
$ErrorActionPreference = 'SilentlyContinue'
$Menu = 0
$Subs = #(Get-AzSubscription | Select-Object Name, ID, TenantId)
Write-Host "Please select the subscription you want to use:" -ForegroundColor Green;
ForEach-Object {Write-Host ""}
$Subs | ForEach-Object {Write-Host "[$($Menu)]" -ForegroundColor Cyan -NoNewline ; Write-host ". $($_.Name)"; $Menu++; }
ForEach-Object {Write-Host ""}
ForEach-Object {Write-Host "[S]" -ForegroundColor Yellow -NoNewline ; Write-host ". To switch Azure Account."}
ForEach-Object {Write-Host ""}
ForEach-Object {Write-Host "[Q]" -ForegroundColor Red -NoNewline ; Write-host ". To quit."}
ForEach-Object {Write-Host ""}
$selection = Read-Host "Please select the Subscription Number - Valid numbers are 0 - $($Subs.count -1), S to switch Azure Account or Q to quit"
If ($selection -eq 'S') {
Get-AzContext | ForEach-Object {Clear-AzContext -Scope CurrentUser -Force}
Select-Azure
Select-Subs
}
If ($selection -eq 'Q') {
Clear-Host
Exit
}
If ($Subs.item($selection) -ne $null)
{ Return #{name = $subs[$selection].Name; ID = $subs[$selection].ID}
}
}
Function Resolve-AzAdGroupMembers {
<#
.SYNOPSIS
Gets list of Azure Active Directory groups and its members
#>
param(
[guid]
$GroupObjectId,
$GroupList
)
$VerbosePreference = 'continue'
Write-Verbose -Message ('Resolving {0}' -f $GroupObjectId)
$group = $GroupList | Where-Object -Property Id -EQ -Value $GroupObjectId
$groupMembers = Get-AzADGroupMember -GroupObjectId $GroupObjectId
Write-Verbose -Message ('Found members {0}' -f ($groupMembers.DisplayName -join ', '))
$parentGroup = #{
Id = $group.Id
DisplayName = $group.DisplayName
}
$groupMembers |
Where-Object -Property Type -NE -Value Group |
Select-Object -Property Id, DisplayName, #{
Name = 'ParentGroup'
Expression = { $parentGroup }
}
$groupMembers |
Where-Object -Property type -EQ -Value Group |
ForEach-Object -Process {
Resolve-AzAdGroupMembers -GroupObjectId $_.Id -GroupList $GroupList
}
}
Main Part of Script
Write-Output "Running login script"
Login # Login to Azure
$SubscriptionSelection = Select-Subs # Runs function to get Azure subscriptions available to user and sets the subscription to the users choice.
Select-AzSubscription -SubscriptionName $SubscriptionSelection.Name -ErrorAction Stop
## Get current Azure Subscription Name to be used in reporting output
$Azuresub = $SubscriptionSelection.Name -replace , '/'
ForEach-Object {Write-Host "Getting Azure AD Groups" -ForegroundColor Yellow -NoNewline}
ForEach-Object {Write-Host "`r`n========================================" -ForegroundColor Yellow -NoNewline}
ForEach-Object {Write-Host "`nThis process can take a while to run since it is checking every Azure Role and its corresponding assignments." -ForegroundColor Yellow -NoNewline }
$GroupList = (Get-AzADGroup)
ForEach-Object {Write-Host "Getting Role Assignments" -ForegroundColor Yellow -NoNewline}
ForEach-Object {Write-Host "`r`n========================================" -ForegroundColor Yellow -NoNewline}
$roleAssignments = Get-AzRoleAssignment -IncludeClassicAdministrators
## Loop through each role assignment to determine the user assigned to that role.
$members = $roleAssignments | ForEach-Object -Process {
Write-Verbose -Message ('Processing Assignment {0}' -f $_.RoleDefinitionName)
$roleAssignment = $_
if($roleAssignment.ObjectType -eq 'Group')
{
Resolve-AzAdGroupMembers -GroupObjectId $roleAssignment.ObjectId -GroupList $GroupList `
| Select-Object -Property Id,
DisplayName,
ParentGroup, #{
Name = 'RoleDefinitionName'
Expression = { $roleAssignment.RoleDefinitionName }
}, #{
Name = 'Scope'
Expression = { $roleAssignment.Scope }
}, #{
Name = 'CanDelegate'
Expression = { $roleAssignment.CanDelegate }
}
}
else
{
$roleAssignment | Select-Object -Property #{
Name = 'Id'
Expression = { $_.ObjectId }
},
DisplayName,
#{
Name = 'RoleDefinitionName'
Expression = { $roleAssignment.RoleDefinitionName }
},
Scope,
CanDelegate
}
}
Generating CSV Output for reporting
$outtbl = #()
$members | ForEach-Object {
$x = New-Object PSObject -Property #{
Subscription = $Azuresub -join ','
ActiveDirID = $_.Id -join ','
DisplayName = $_.DisplayName -join ','
ParentGroupID = $_.ParentGroup.Id -join ','
ParentGroupDisplayName = $_.ParentGroup.DisplayName -join ','
RoleDefinitionName = $_.RoleDefinitionName -join ','
Scope = $_.Scope
}
$outtbl += $x
}
$outtbl | Select-Object Subscription,ActiveDirID,DisplayName,ParentGroupID,ParentGroupDisplayName,RoleDefinitionName, Scope |Export-CSV -path $($PSScriptRoot + "\" + "$Azuresub" + " Azure RBAC Audit.csv") -NoTypeInformation
ForEach-Object {Write-Host " `r`nRBAC Audit has completed. Your CSV file is located: $($PSScriptRoot + "\" + "$Azuresub" + " Azure RBAC Audit.csv")" -ForegroundColor Green -NoNewline }
Above code is working fine for complete subscription but we need to filter the output only for resoucegroup. so how to add one more function to get output only based on reouce group.
https://github.com/arnoldna/RBACReporting/blob/master/AzureSubscriptionRBACAudit.ps1
For your requirement, just use the -ResourceGroupName parameter in the command Get-AzRoleAssignment to specify the resource group you want in Main Part of Script.
$roleAssignments = Get-AzRoleAssignment -IncludeClassicAdministrators -ResourceGroupName <ResourceGroupName>
Note: The RBAC role permissions are inherited, e.g. if a user/service principal/AAD group has an RBAC role at the subscription/management group scope, it will also have the permission at all the resource groups located in the subscription/management group, so the command above will also get the role assignments that assigned at the subscription/management group scope, the management group is a higher scope than subscription, refer to this link.
So if you just want to get the role assignment that directly assigned to the resource group/single resource in the resource group, modify the command as below, it depends on your reqirement.
$roleAssignments = Get-AzRoleAssignment -IncludeClassicAdministrators -ResourceGroupName <ResourceGroupName> | Where-Object {$_.Scope -like '/subscriptions/*/resourceGroups/*'}

How to do a full site collecion level re-index in sharepoint online?

After adding a new managed property I need to do a full site collection level or tenant level re-indexing to get the search crawler run. But I could not find a way to do this in SharePoint online.Is there a way to do this?
There is a script to re-index a SharePoint online site collection via CSOM. I think this will help you to re-index your 100+ subsites.
#Grab the tenant information
$username = Read-Host "Enter the tenant admin account login"
$password = Read-host -AsSecureString "Enter the admin account password"
$siteUrl = Read-Host "Please enter the site collection URL to re-index"
Write-Host "Would you like to populate the managed properties on all lists post re-crawl (ex. Cross Site Publishing)?" -ForegroundColor Green
Write-Host "1. Yes - enable managed properties on all lists in this site!" -ForegroundColor Cyan
Write-Host "2. No - Turn off managed properties in all lists in the site!" -ForegroundColor Blue
Write-Host "3. No - Just re-index the site!" -ForegroundColor Red
$enableAllManagedProperties = Read-Host "Choice [1-3]?"
$date = (Get-Date).ToString("yyyyMMdd")
#Load the assemblies
$load1 = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client")
$load2 = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime")
$load3 = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.UserProfiles")
if (!$load1) {
$script_folder = (Split-Path -Parent $MyInvocation.MyCommand.Path)
$load1 = [System.Reflection.Assembly]::LoadFile($script_folder + "\Microsoft.SharePoint.Client.dll")
if (!$load1) {
Write-Host "Failed to load Microsoft.SharePoint.Client.dll - please ensure it is in the same location as the PS1." -ForegroundColor Red
write-host "Alternatively, install the SPO Client Components SDK from http://www.microsoft.com/en-us/download/details.aspx?id=42038" -ForegroundColor Red
exit;
}
}
if (!$load2) {
$script_folder = (Split-Path -Parent $MyInvocation.MyCommand.Path)
$load2 = [System.Reflection.Assembly]::LoadFile($script_folder + "\Microsoft.SharePoint.Client.Runtime.dll")
if (!$load2) {
Write-Host "Failed to load Microsoft.SharePoint.Client.Runtime.dll - please ensure it is in the same location as the PS1." -ForegroundColor Red
write-host "Alternatively, install the SPO Client Components SDK from http://www.microsoft.com/en-us/download/details.aspx?id=42038" -ForegroundColor Red
exit;
}
}
if (!$load3) {
$script_folder = (Split-Path -Parent $MyInvocation.MyCommand.Path)
$load3 = [System.Reflection.Assembly]::LoadFile($script_folder + "\Microsoft.SharePoint.Client.UserProfiles.dll")
if (!$load3) {
Write-Host "Failed to load Microsoft.SharePoint.Client.UserProfiles.dll - please ensure it is in the same location as the PS1." -ForegroundColor Red
write-host "Alternatively, install the SPO Client Components SDK from http://www.microsoft.com/en-us/download/details.aspx?id=42038" -ForegroundColor Red
exit;
}
}
function Connect-SPO($siteUrl) {
$clientContext = New-Object Microsoft.SharePoint.Client.ClientContext($siteUrl)
$clientContext.Credentials = $credentials
if (!$clientContext.ServerObjectIsNull.Value) {
Write-Host "Connected to SharePoint Online site: '$siteUrl'" -ForegroundColor Green
}
$rootWeb = $clientContext.Web
processWeb($rootweb)
}
function processWeb($web) {
$subWebs = $web.Webs
$clientContext.Load($web)
$clientContext.Load($web.AllProperties)
$clientContext.Load($subWebs)
try
{
$clientContext.ExecuteQuery()
}
catch
{
write-host "Error on $($clientContext) - $($_)" -ForegroundColor Red
Write-Host "It's possible you are not an administrator on the site collection - Exiting the script" -ForegroundColor Red
Sleep 10
Exit
}
Write-Host "Web URL:" $web.Url -ForegroundColor White
if ( $enableAllManagedProperties -ne "3" ) {
Set-AllManagedProperties -web $web -clientContext $clientContext -enableAllManagedProps $enableAllManagedProperties
}
[int]$version = 0
$allProperties = $web.AllProperties
if ( $allProperties.FieldValues.ContainsKey("vti_searchversion") -eq $true ) {
$version = $allProperties["vti_searchversion"]
}
$version++
$allProperties["vti_searchversion"] = $version
Write-Host "-- Updated search version: " $version -ForegroundColor Green
$web.Update()
$clientContext.ExecuteQuery()
# No need to process subwebs if we only mark site collection for indexing
if ($enableAllManagedProperties -ne "3") {
foreach ($subWeb in $subWebs) {
processWeb($subWeb)
}
}
}
function Set-AllManagedProperties( $web, $clientContext, $enableAllManagedProps ) {
$lists = $web.Lists
$clientContext.Load($lists)
$clientContext.ExecuteQuery()
foreach ($list in $lists) {
Write-Host "--" $list.Title
if ( $list.NoCrawl ) {
Write-Host "-- Skipping list due to not being crawled" -ForegroundColor Yellow
continue
}
$skip = $false;
$eventReceivers = $list.EventReceivers
$clientContext.Load($eventReceivers)
$clientContext.ExecuteQuery()
foreach ( $eventReceiver in $eventReceivers ) {
if ( $eventReceiver.ReceiverClass -eq "Microsoft.SharePoint.Publishing.CatalogEventReceiver" ) {
$skip = $true
Write-Host "-- Skipping list as it's published as a catalog" -ForegroundColor Yellow
break
}
}
if ( $skip ) {continue}
$folder = $list.RootFolder
$props = $folder.Properties
$clientContext.Load($folder)
$clientContext.Load($props)
$clientContext.ExecuteQuery()
if ( $enableAllManagedProps -eq "1" ) {
Write-Host "-- Enabling all managed properties" -ForegroundColor Green
$props["vti_indexedpropertykeys"] = "UAB1AGIAbABpAHMAaABpAG4AZwBDAGEAdABhAGwAbwBnAFMAZQB0AHQAaQBuAGcAcwA=|SQBzAFAAdQBiAGwAaQBzAGgAaQBuAGcAQwBhAHQAYQBsAG8AZwA=|"
$props["IsPublishingCatalog"] = "True"
}
if ( $enableAllManagedProps -eq "2" ) {
Write-Host "-- Disabling all managed properties" -ForegroundColor Green
$props["vti_indexedpropertykeys"] = $null
$props["IsPublishingCatalog"] = $null
}
$folder.Update()
$clientContext.ExecuteQuery()
}
}
#SPO Credentials
$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($username, $Password)
Connect-SPO -siteUrl $siteurl
if ($version -ne "$null" ) {
Write-Host "Re-index has should now have been succesfully triggered for $siteurl - Please remember that this can take some time before the crawl picks up the index." -ForegroundColor Cyan
}
https://gallery.technet.microsoft.com/office/Re-index-a-Sharepoint-e70d285b
Note: This will not improve crawl time, merely ensure items are re-indexed.
You need to go to the Site Settings > Search and Offline Availability link and then press the reindex option as in below image.
You need to be site collection admin or owner to view these settings:
Updated as per comments:
To trigger a full site collections reindex, you need to make use of PS script as in this link.

Change multiple files content type programatically using CSOM for SharePoint Online

I am attempting to change all the files in a library from one content type to another. This is in SharePoint Online so I'm using the CSOM. I am new to this so I'm stuck at where to go from what I have below.
I think my biggest issue is getting the values of the content types. That and I'm so used to SP On Premise I'm having trouble grasping this CSOM stuff. Much thanks to anyone that can help point me in the right direction!
#Load necessary module to connect to SPOService
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime") | Out-Null
#Login Information for script
$User = "user"
$Pass = "password"
$WebUrl = "SiteURL"
#Connect to SharePoint Online service
Write-Host "Logging into SharePoint online service." -ForegroundColor Green
$Context = New-Object Microsoft.SharePoint.Client.ClientContext($WebUrl)
$Context.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($User, (ConvertTo-SecureString $Pass -AsPlainText -Force))
#Get the Necessary List
Write-Host "Getting the required list." -ForegroundColor Green
$List = $Context.Web.Lists.GetByTitle("TestLibrary")
Write-Host "Getting the Content Types." -ForegroundColor Green
$oldCT = $list.ContentTypes("OldCTName")
$newCT = $list.ContentTypes("NewCTName")
$newCTID = $newCT.ID
$Query = [Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery(1000);
$Items = $List.GetItems($Query);
$Context.Load($Items);
$Context.ExecuteQuery();
#Check if the values specified for the content types actually exist on the list
if (($oldCT -ne $null) -and ($newCT -ne $null))
{
#Go through each item in the list
#Edit existing list items
foreach($item in $Items)
{
#Check if the item content type currently equals the old content type specified
if ($_.ContentType.Name -eq $oldCT.Name)
{
#Check the check out status of the file
if ($_.File.CheckOutType -eq "None")
{
#Change the content type association for the item
$_.File.CheckOut()
write-host "Resetting content type for file" $_.Name "from" $oldCT.Name "to" $newCT.Name
$_["ContentTypeId"] = $newCTID
$_.Update()
$_.File.CheckIn("Content type changed to " + $newCT.Name, 1)
}
else
{
write-host "File" $_.Name "is checked out to" $_.File.CheckedOutByUser.ToString() "and cannot be modified"
}
}
else
{
write-host "File" $_.Name "is associated with the content type" $_.ContentType.Name "and shall not be modified"
}
}
}
else
{
write-host "One of the content types specified has not been attached to the list"$list.Title
}
$Context.ExecuteQuery();
}

downloading a file from SharePoint Online with PowerShell

I have a requirement to download files from a sharepoint online document library using powershell
I've managed to get to the point where the download should happen but no luck.
I know its something to do with how I am using the stream/writer
any hints would be greatly appreciated
*Edit
No error messages are thrown just 0 length files in my local Directory
$SPClient = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client")
$SPRuntime = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime")
$webUrl = Read-Host -Prompt "HTTPS URL for your SP Online 2013 site"
$username = Read-Host -Prompt "Email address for logging into that site"
$password = Read-Host -Prompt "Password for $username" -AsSecureString
$folder = "PoSHTest"
$destination = "C:\\test"
$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($webUrl)
$ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($username, $password)
$web = $ctx.Web
$lists = $web.Lists.GetByTitle($folder)
$query = [Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery(10000)
$result = $lists.GetItems($query)
$ctx.Load($Lists)
$ctx.Load($result)
$ctx.ExecuteQuery()
#Edited the foreach as per #JNK
foreach ($File in $result) {
Write-host "Url: $($File["FileRef"]), title: $($File["FileLeafRef"]) "
$binary = [Microsoft.SharePoint.Client.File]::OpenBinaryDirect($ctx,$File["FileRef"])
$Action = [System.IO.FileMode]::Create
$new = $destination + "\\" + $File["FileLeafRef"]
$stream = New-Object System.IO.FileStream $new, $Action
$writer = New-Object System.IO.BinaryWriter($stream)
$writer.write($binary)
$writer.Close()
}
You could also utilize WebClient.DownloadFile Method by providing SharePoint Online credentials to download the resource from SharePoint Online as demonstrated below.
Prerequisites
SharePoint Online Client Components SDK have to be installed on the machine running the script.
How to download a file in SharePoint Online/O365 in PowerShell
Download-File.ps1 function:
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Client.Runtime")
Function Download-File([string]$UserName, [string]$Password,[string]$FileUrl,[string]$DownloadPath)
{
if([string]::IsNullOrEmpty($Password)) {
$SecurePassword = Read-Host -Prompt "Enter the password" -AsSecureString
}
else {
$SecurePassword = $Password | ConvertTo-SecureString -AsPlainText -Force
}
$fileName = [System.IO.Path]::GetFileName($FileUrl)
$downloadFilePath = [System.IO.Path]::Combine($DownloadPath,$fileName)
$client = New-Object System.Net.WebClient
$client.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $SecurePassword)
$client.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED", "f")
$client.DownloadFile($FileUrl, $downloadFilePath)
$client.Dispose()
}
Usage
Download-File -UserName "username#contoso.onmicrosoft.com" -Password "passowrd" -FileUrl https://consoto.sharepoint.com/Shared Documents/SharePoint User Guide.docx -DownloadPath "c:\downloads"
I was able to download the file successfully with the following relevant code snippet. You should be able to extend it for your situation.
Add-Type –Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type –Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
$siteUrl = Read-Host -Prompt "Enter web URL"
$username = Read-Host -Prompt "Enter your username"
$password = Read-Host -Prompt "Enter password" -AsSecureString
$source = "/filepath/sourcefilename.dat" #server relative URL here
$target = "C:/detinationfilename.dat" #URI of the file locally stored
$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($siteUrl)
$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($username, $password)
$ctx.Credentials = $credentials
[Microsoft.SharePoint.Client.FileInformation] $fileInfo = [Microsoft.SharePoint.Client.File]::OpenBinaryDirect($ctx,$source);
[System.IO.FileStream] $writeStream = [System.IO.File]::Open($target,[System.IO.FileMode]::Create);
$fileInfo.Stream.CopyTo($writeStream);
$writeStream.Close();
While the CSOM code above likely can be made to work I find it easier to use the web client method.
(from http://soerennielsen.wordpress.com/2013/08/25/use-csom-from-powershell/)
I've used the code below, to retrieve a bunch of files (metadata from CSOM queries) to a folder (using your $result collection, other params should be adjusted a bit):
#$siteUrlString site collection url
#$outPath path to export directory
$siteUri = [Uri]$siteUrlString
$client = new-object System.Net.WebClient
$client.UseDefaultCredentials=$true
if ( -not (Test-Path $outPath) ) {
New-Item $outPath -Type Directory | Out-Null
}
$result |% {
$url = new-object Uri($siteUri, $_["FileRef"])
$fileName = $_["FileLeafRef"]
$outFile = Join-Path $outPath $fileName
Write-Host "Downloading $url to $outFile"
try{
$client.DownloadFile( $url, $outFile )
}
catch{
#one simple retry...
try{
$client.DownloadFile( $url, $outFile )
}
catch{
write-error "Failed to download $url, $_"
}
}
}
The trick here is the
$client.UseDefaultCredentials=$true
which will authenticate the webclient for you (as the current user).
The direct and almost shortest answer to the question is simply:
$url = 'https://the.server/path/to/the/file.txt'
$outfile = "$env:userprofile\file.txt"
Invoke-WebRequest -Uri $url -OutFile $outfile -Credential (Get-Credential)
This works at least in Powershell 5.1...
So I gave up on this. it turned out to be much easier to write an SSIS script component to do the job.
I have awarded Soeren as he posted some code that will work for regular websites but not sodding SharePoint Online.
Thanks Sorean!
Short an easy approach to download a file from sharepoint online, using just powershell and sharepoint online url ( no pnp powershell )
This approach can also be used to perform Sharepoint REST queries, with just powershell and sharepoint REST api
# required MS dependencies
# feel free to download them from here https://www.microsoft.com/en-us/download/details.aspx?id=42038
Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll' -ErrorAction Stop
Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll' -ErrorAction Stop
# prepare passwords
$spCredential = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($user, $(ConvertTo-SecureString -AsPlainText $pass -Force))
# prepare and perform rest api query
$Context = New-Object Microsoft.SharePoint.Client.ClientContext($targetSiteUrl)
$Context.Credentials = $spCredential
try {
#this may return an error, but still will finish context setup
$Context.ExecuteQuery()
}
catch {
write-host "TODO: fix executeQuery() err 400 bug" -ForegroundColor Yellow
}
$AuthenticationCookie = $Context.Credentials.GetAuthenticationCookie($targetSiteUrl, $true)
$WebSession = New-Object Microsoft.PowerShell.Commands.WebRequestSession
$WebSession.Credentials = $Context.Credentials
$WebSession.Cookies.SetCookies($targetSiteUrl, $AuthenticationCookie)
$WebSession.Headers.Add("Accept", "application/json;odata=verbose")
Invoke-WebRequest -Uri $spFileUrl -OutFile $outputFilePath -WebSession $WebSession -errorAction Stop
Where
$outputFilePath is the target output file in which you want to save the remote file.
$targetSiteUrl is the target sp site url.
$spFileUrl is the "[sharepoint file full url]"
$user plain text sp user email
$pass plain text sp user pass

Enabling Sharepoint Features With Powershell

I am new to PowerShell and have been asked to modify a script that is used to activate features on a site. The script has some latency issues between the two feature activations, so I decided to make a new function that will enable the feature and sleep or delay until the feature is finished enabling. Will this work? And if so, how can I tell that the feature is finished activating?
# This is a function that enable's a Sharepoint Feature and Sleeps Until Its Finished Enabling
function Feature-Enable
{param ([string]$ID, [string]$URL)
#Enable Feature
Enable-SPFeature -Identity $ID -url $URL -Confirm:$false
#Sleep Until Feature is Done Enabling
}
#Set parameters/variables for script
$serverName = "someServerName"
$rootwebUrl = "someRootUrl"
$currentpath=Split-Path -Path $MyInvocation.MyCommand.Path -Parent
$siteURL = "http://" + $servername + $rootwebURL
$start = Get-Date -DisplayHint Time
# check to ensure Microsoft.SharePoint.PowerShell is loaded
$snapin = Get-PSSnapin | Where-Object {$_.Name -eq 'Microsoft.SharePoint.Powershell'}
if ($snapin -eq $null) {
Write-Host "Loading SharePoint Powershell Snapin"
Add-PSSnapin "Microsoft.SharePoint.Powershell"
}
# Active Site Collection Features (in order)
write-host ""
write-host "----------------------------------------"
write-host "Begin activation of site collection features"
write-host "----------------------------------------"
write-host ""
Feature-Enable –identity "3cbf5d1e-ff2e-48d2-82a4-99b060381268" -URL $siteUrl
#NOTE: POTENTIAL LATENCY ISSUES. MAY NEED TO INSERT DELAY TIMER!
Feature-Enable –identity "bbde524e-9293-468e-84f7-fdb763ffa309" -URL $siteUrl
write-host ""
write-host "----------------------------------------"
write-host "Activation of site collection features - DONE!"
write-host "----------------------------------------"
write-host ""
$end= Get-Date -DisplayHint Time
Write-Host "Started at: " $start " Ended at: " $end;
function WaitForJobToFinish([string]$SolutionFileName)
{
$JobName = "*solution-deployment*$SolutionFileName*"
$job = Get-SPTimerJob | ?{ $_.Name -like $JobName }
if ($job -eq $null)
{
Write-Host 'Timer job not found'
}
else
{
$JobFullName = $job.Name
Write-Host -NoNewLine "Waiting to finish job $JobFullName"
while ((Get-SPTimerJob $JobFullName) -ne $null)
{
Write-Host -NoNewLine .
Start-Sleep -Seconds 2
}
Write-Host "Finished waiting for job.."
}
}

Resources