I want to get all lists in site using sharepoint that without hidden list. Because i know that, when we list all lists, we will receive all including hidden list. Please help me, thank you very much
Try PnP PowerShell.
#region Variables
$Username = "user#tenant.onmicrosoft.com"
$Password = "password"
$siteURL = "https://tenant.sharepoint.com/sites/lee"
#endregion Variables
#region Credentials
[SecureString]$SecurePass = ConvertTo-SecureString $Password -AsPlainText -Force
[System.Management.Automation.PSCredential]$PSCredentials = New-Object System.Management.Automation.PSCredential($Username, $SecurePass)
#endregion Credentials
Connect-PnPOnline -Url $siteURL -Credentials $PSCredentials
$lists=Get-PnPList | ?{$_.Hidden -eq $false}
foreach($list in $lists){
Write-Host $list.Title +"Hidden:" $list.Hidden
}
write-host "done"
Related
Currently we get an access token and then pass this token to PowerShell script to loop across all ODFB personal sites.
$url = "https://XXXXX-admin.sharepoint.com"
$conn = Connect-PnPOnline -Url $url -AccessToken $access_token -ReturnConnection
$sitecollections = Get-PnPTenantSite -IncludeOneDriveSites:$true -Filter "Url -like '-my.sharepoint.com/personal/'" -Connection $conn | Select-Object -ExpandProperty Url
foreach ($site in $sitecollections)
{
....
}
It worked successfully for years until it was broken a while ago.
I tried different versions of PnP PowerShell:
PnP version
Error
SharePointPnPPowerShellOnline 3.21.2005.2 (currently used)
Get-PnPTenantSite : Attempted to perform an unauthorized operation.
SharePointPnPPowerShellOnline 3.29.2101.0
Get-PnPTenantSite : The current connection holds no SharePoint context.
PnP.PowerShell 1.10.28
Get-PnPTenantSite : Attempted to perform an unauthorized operation.
If I change script to use an user/password instead the access token, the script works without problems:
$url = "https://XXXXX-admin.sharepoint.com"
$User = "admin#mydomain.com"
$PWord = ConvertTo-SecureString -String "Password" -AsPlainText -Force
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $PWord
$conn = Connect-PnPOnline -Url $url -Credentials $Credential -ReturnConnection
$sitecollections = Get-PnPTenantSite -IncludeOneDriveSites:$true -Filter "Url -like '-my.sharepoint.com/personal/'" -Connection $conn | Select-Object -ExpandProperty Url
foreach ($site in $sitecollections)
{
....
}
So the error happens when the script connects to SP Online using an access token.
Perhaps the some things were changed. But what exactly? Have some scope to be added when an access token is requested?
Or have some new permissions to be added for the application in Azure AD?
Update:
Modified the script (added Write-Output "Connection is:" $conn | fl) to provide more details about connection and got the difference in ConnectionType property when SharePointPnPPowerShellOnline 3.21.2005.2 is used:
When an access token is used (and the script doesn't work properly), ConnectionType : O365
When an access token is used (and the script works fine), ConnectionType : TenantAdmin
Hi I'm trying to export a list of AD users based on "Last Logon"
I've scripted using base powershell however I'd be interested if anyone can find a solution using "AzureAD to Powershell" commands.
I've gotten as far as getting the list however I cannot export it to any file type because of how it generates through the loop.
End result I'm looking for is to be able to organize the data to see which users have been inactive?
Import-Module ActiveDirectory
function Get-ADUserLastLogon([string]$userName) {
$dcs = Get-ADDomainController -Filter {Name -like "*"}
$time = 0
foreach($dc in $dcs) {
$hostname = $dc.HostName
$user = Get-ADUser $userName | Get-ADObject -Properties lastLogon
if($user.LastLogon -gt $time) {
$time = $user.LastLogon
}
}
$dt = [DateTime]::FromFileTime($time)
Write-Host $username "last logged on at:" $dt
}
$unames = Get-ADUser -Filter 'ObjectClass -eq "User"' | Select -Expand SamAccountName
foreach ($uname in $unames) { Get-ADUserLastLogon($uname); }
In Azure AD, we can get all user Sign-ins records on Azure Portal or using Azure AD PowerShell.
If you are looking for a way by PowerShell to export Azure AD users last login list with user account status (enabled or not), just try the code below:
Connect-AzureAD
$AllUsers = Get-AzureADUser -All $true
$AllSiginLogs = Get-AzureADAuditSignInLogs -All $true
$results = #()
foreach($user in $AllUsers){
$LoginRecord = $AllSiginLogs | Where-Object{ $_.UserId -eq $user.ObjectId } | Sort-Object CreatedDateTime -Descending
if($LoginRecord.Count -gt 0){
$lastLogin = $LoginRecord[0].CreatedDateTime
}else{
$lastLogin = 'no login record'
}
$item = #{
userUPN=$user.UserPrincipalName
userDisplayName = $user.DisplayName
lastLogin = $lastLogin
accountEnabled = $user.AccountEnabled
}
$results += New-Object PSObject -Property $item
}
$results | export-csv -Path d:\result.csv -NoTypeInformation
export to .csv file Result:
There is one thing that you should know, for different Azure AD service tier, the time that Azure AD keep these data is different, details see here.
Running EnsureUser on an existing domain account give an error that the user could not be found. Same command(s) works fine in PowerShell on SharePoint server locally. I am able to create a SharePoint group remotely, just can't add a user to that group.
$site = new-object Microsoft.SharePoint.SPSite("http://sharepoint.company.com/dev")
$web = $site.OpenWeb()
function GrantUserpermission($userName)
{
$folder.BreakRoleInheritance("true")
$web.SiteGroups.Add("test_group", $web.Site.Owner, $web.Site.Owner, "Desc")
$ownerGroup = $web.SiteGroups["test_group"]
$ownerGroup.AllowMembersEditMembership = $true
$ownerGroup.Update()
$sitename = Get-SPWeb http://sharepoint.company.com/dev
$EnsuredUser = $sitename.EnsureUser("domain\user")
Set-SPUser -Identity $EnsuredUser -web $sitename -group "test_group"
$AddGroup = $web.SiteGroups["test_group"]
$roleAssignment = new-object Microsoft.sharepoint.SPRoleAssignment($AddGroup)
$roleDefinition = $web.RoleDefinitions["Contribute"]
$roleAssignment.RoleDefinitionBindings.add($roleDefinition)
$folder.RoleAssignments.Add($roleAssignment)
$folder.SystemUpdate()
Check if the domain user exists before use the EnsureUser method.
If you want to add SharePoint user to group in remote server, we can use CSOM with PowerShell to achieve it.
$url="http://sharepoint.company.com/dev"
$userName="administrator"
$password="**"
$domain="test"
$sGroup="test_group"
$sUserToAdd="domain\user"
$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($url)
$credentials = New-Object System.Net.NetworkCredential($userName,$password,$domain)
$ctx.Credentials = $credentials
$groups=$ctx.Web.SiteGroups
$ctx.Load($groups)
#Getting the specific SharePoint Group where we want to add the user
$group=$groups.GetByName($sGroup)
$ctx.Load($group)
#Ensuring the user we want to add exists
$user = $ctx.Web.EnsureUser($sUserToAdd)
$ctx.Load($user)
$userToAdd=$group.Users.AddUser($user)
$ctx.Load($userToAdd)
$ctx.ExecuteQuery()
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
Let's say I have a PSCrendential object in PowerShell that I created using Get-Credential.
How can I validate the input against Active Directory ?
By now I found this way, but I feel it's a bit ugly :
[void][System.Reflection.Assembly]::LoadWithPartialName("System.DirectoryServices.AccountManagement")
function Validate-Credentials([System.Management.Automation.PSCredential]$credentials)
{
$pctx = New-Object System.DirectoryServices.AccountManagement.PrincipalContext([System.DirectoryServices.AccountManagement.ContextType]::Domain, "domain")
$nc = $credentials.GetNetworkCredential()
return $pctx.ValidateCredentials($nc.UserName, $nc.Password)
}
$credentials = Get-Credential
Validate-Credentials $credentials
[Edit, two years later] For future readers, please note that Test-Credential or Test-PSCredential are better names, because Validate is not a valid powershell verb (see Get-Verb)
I believe using System.DirectoryServices.AccountManagement is the less ugly way:
This is using ADSI (more ugly?):
$cred = Get-Credential #Read credentials
$username = $cred.username
$password = $cred.GetNetworkCredential().password
# Get current domain using logged-on user's credentials
$CurrentDomain = "LDAP://" + ([ADSI]"").distinguishedName
$domain = New-Object System.DirectoryServices.DirectoryEntry($CurrentDomain,$UserName,$Password)
if ($domain.name -eq $null)
{
write-host "Authentication failed - please verify your username and password."
exit #terminate the script.
}
else
{
write-host "Successfully authenticated with domain $domain.name"
}
I was having a similar issue with an installer and required to verify the service account details supplied. I wanted to avoid using the AD module in Powershell as I wasn't 100% this would be installed on the machine running the script.
I did the test using the below, it is slightly dirty but it does work.
try{
start-process -Credential $c -FilePath ping -WindowStyle Hidden
} catch {
write-error $_.Exception.Message
break
}