I would like to create a user on Win Server 2022, without admin rights, who can modify the content of administrator groups.
I have added this user a full control over these groups with a PS script, but after a while, Windows automatically removes my user from there.
Is threre a way to stay there permanently?
$PWord = ConvertTo-SecureString -String "# ... #" -AsPlainText -Force
New-ADUser -Name "creator" -SamAccountName "creator" -UserPrincipalName "creator" -DisplayName "creator" -Enabled $true -AccountPassword $PWord -ChangePasswordAtLogon $false -PasswordNeverExpires $true
Add-AdGroupMember -Identity "S-1-5-32-548" -Members "creator"
Add-AdGroupMember -Identity "S-1-5-32-580" -Members "creator"
New-ADOrganizationalUnit -Name "MyDomain"
enable-psremoting -Force
$sid = (Get-ADDomain -Server 127.0.0.1 | Select DomainSID | ft -HideTableHeaders | out-string).Trim()
$groups = #("S-1-5-32-544",$($sid+"-512"),$($sid+"-518"),$($sid+"-519"),$($sid+"-520"))
$colRights = [System.DirectoryServices.ActiveDirectoryRights]"GenericAll"
$objType =[System.Security.AccessControl.AccessControlType]::Allow
$objUser = New-Object System.Security.Principal.NTAccount("creator")
$objACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule ($objUser, $colRights, $objType)
foreach($group in $groups)
{
$objACL=Get-ACL "AD:$((get-adgroup $group).DistinguishedName)"
$objACL.AddAccessRule($objACE)
Set-ACL "AD:$((get-adgroup $group).DistinguishedName)" $objACL
}
$OU = (Get-ADOrganizationalUnit -Filter {Name -eq 'MyDomain'}).DistinguishedName
$ouACL=Get-ACL "AD:$OU"
$ouACL.AddAccessRule($objACE)
Set-ACL "AD:$OU" $ouACL
I am trying hard to get details of all the lists from a SharePoint site collection and export to CSV.
I am trying to run remotely from my machine and it doesn't work. I am not an export CSOM guy so asking for help, please.
I heard from someone that CSOM can run from anywhere and able to get info from SHarePoint 2013 server.
import-module C:\powershell\SharePointPnPPowerShell2013\3.16.1912.0\sharepointpnppowershell2013.psd1 -DisableNameChecking
$username = "testing#domain.com"
$password="Password"
$secureStringPwd = $Password | ConvertTo-SecureString -AsPlainText -Force
$Credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $Username, $secureStringPwd
$connection=Connect-PnPOnline -Url https://cys.test.domain.com -Credentials $Credentials
$siteurl = "https://cys.test.domain.com/sites/testsite"
function Get-DocInventory([string]$siteUrl) {
$site = New-Object Microsoft.SharePoint.SPSite "https://cys.test.domain.com"
$web = Get-SPWeb "https://cys.test.domain.com/sites/testsite"
foreach ($list in $web.Lists) {
foreach ($item in $list.Items) {
#foreach($version in $item.Versions){
$data = #{
"List Name" = $list.Title
"Created By" = $item["Author"]
"Created Date" = $item["Created"]
"Modified By" = $item["Editor"]
"Modified Date" = $item["Modified"]
"Item Name" = $item.File.Name
"URL"=$web.Site.MakeFullUrl("$($web.ServerRelativeUrl.TrimEnd('/'))/$($item.Url)");
}
New-Object PSObject -Property $data | Select "List Name", "Item Name", "Created By", "Created Date", "Modified By", "Modified Date", "URL"
}
#}
$web.Dispose();
}
}
Get-DocInventory | Export-Csv -NoTypeInformation -Path "d:\test\test.csv"
If you are using SharePoint 2013 On-Premise, try to install SharePoint 2013 CSOM firstly:
SharePoint Server 2013 Client Components SDK
Then use this script to get list details in a site collection includes sub sites:
#Load SharePoint CSOM Assemblies
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"
#Variables for Processing
$SiteUrl= "http://sp/sites/devtest"
$username="administrator"
$password="******"
$domain="Contoso"
#Setup Credentials to connect
$Credentials = New-Object System.Net.NetworkCredential($username, $password, $domain)
Try {
#Function to Get all lists from the web
Function Get-SPOList($Web)
{
#Get All Lists from the web
$Lists = $Web.Lists
$Context.Load($Lists)
$Context.ExecuteQuery()
#Get all lists from the web
ForEach($List in $Lists)
{
#Get the List Name
Write-host $List.Title
Write-host $List.Created
}
}
#Function to get all webs from given URL
Function Get-SPOWeb($WebURL)
{
#Set up the context
$Context = New-Object Microsoft.SharePoint.Client.ClientContext($WebURL)
$Context.Credentials = $Credentials
$Web = $context.Web
$Context.Load($web)
#Get all immediate subsites of the site
$Context.Load($web.Webs)
$Context.executeQuery()
#Call the function to Get Lists of the web
Write-host "Processing Web :"$Web.URL
Get-SPOList $Web
#Iterate through each subsite in the current web
foreach ($Subweb in $web.Webs)
{
#Call the function recursively to process all subsites underneaththe current web
Get-SPOWeb($SubWeb.URL)
}
}
#Call the function to get all sites
Get-SPOWeb $SiteUrl
}
catch {
write-host "Error: $($_.Exception.Message)" -foregroundcolor Red
}
Sharepoint Office 365 automatically adds links to most viewed pages. How to prevent it. It is hard to hide every newly appeared link from Site Settings > Navigation Settings. Thank you!
You could delete Recent node from Left Navigation via SharePoint CSOM API.
Prerequisites: SharePoint Online Client Components SDK
The following example demonstrates how to delete Recent node from Left Navigation in PowerShell:
Add-Type –Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type –Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
Function Get-Context([string]$Url,[string]$Username,[string]$Password){
$SecurePassword = $Password | ConvertTo-SecureString -AsPlainText -Force
$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $SecurePassword)
$ctx = New-Object Microsoft.SharePoint.Client.ClientContext($url)
$ctx.Credentials = $credentials
return $ctx
}
Function Delete-NavigationNode([Microsoft.SharePoint.Client.Web]$Web,[string]$NodeTitle){
$ctx = $Web.Context
$nodes = $Web.Navigation.QuickLaunch
$ctx.Load($nodes)
$ctx.ExecuteQuery()
$node = $nodes.GetEnumerator() | where { $_.Title -eq $NodeTitle } | Select -First 1
$node.DeleteObject()
$ctx.ExecuteQuery()
}
$Url = "https://contoso.sharepoint.com/"
$Username = "jdoe#contoso.onmicrosoft.com"
$Password = ""
$ctx = Get-Context -Url $Url -Username $Username -Password $Password
Delete-NavigationNode -Web $ctx.Web -NodeTitle "Recent"
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
Below is my code:
$s = Get-WmiObject -computer 10.10.zz.zz Win32_Service -Filter "Name='XXX'" -credential (Get-Credential XXXXXX\fanwx)
$s.stopservice()
copy-item D:\.....\aaa.exe -destination \\10.10.zz.zz\c$\vvv\
copy-item D:\.....\aaa.pdb -destination \\10.10.zz.zz\c$\vvv\
$s.startservice()
everytime executed, will be prompted enter the password of the remote server. Is there a way allowed me only enter once in powershell OR read the credential in Credential Manager?
Thanks.
Just start by
$cred = Get-Credential "XXXXXX\fanwx"
and after :
$s = Get-WmiObject -computer 10.10.zz.zz Win32_Service -Filter "Name='XXX'" -credential $cred
You can put the password on the disk :
PS > $cred.Password | ConvertFrom-SecureString | Set-Content c:\temp\password.txt
And retreive it with :
$password = Get-Content c:\temp\password.txt | ConvertTo-SecureString
$cred = New-Object System.Management.Automation.PsCredential "UserName",$password