adding file to document library - powershell

Here is my document library looks like. I have 2 content types with my document library. 1 content type is based on Document and the other content type is based on "Link to a document" type.
I am trying to upload some files using powershell script. I am using a csv file to read line by line and upload files to document library. I am getting error on $i.fileNameASPX. Powershell tells me that Missing expression after , . So what to do.
if($i.ContentType = "LegalLink2Document")
{
$itemType = $docLibrary.ContentTypes[$i.ContentType]
$newFile = $docLibrary.RootFolder.Files.Add($i.fileNameASPX, UTF8Encoding.UTF8.GetBytes(builder.ToString()), $true)
$theItem = $newFile.Item
$theItem["ContentTypeId"] = $itemType.Id
$itemUrl = ew-object Microsoft.SharePoint.SPFieldUrlValue()
$itemUrl.Url = $i.fileLinkUrl
$itemUrl.Descrition = $i.URLDESC
$theItem["URL"] = $itemUrl
}

Here is the Simple PowerShell script to upload files to a document library in SharePoint2013
http://soreddymanjunath.blogspot.in/2014/07/add-file-to-document-library-using.html
cls
asnp "*sh*"
$url=Read-Host "Enter Site Url"
$web=Get-SPWeb -Identity $url
if($web)
{
try
{
$list = $web.Lists.TryGetList("Documents")
$files = Get-ChildItem -Path "D:\M" -Force -Recurse
foreach ($file in $files)
{
$stream = $file.OpenRead()
$done= $list.RootFolder.Files.Add($file.Name, $stream, $true)
Write-Host $done.Name "Uploaded into the Site" -BackgroundColor Green
}
}
catch
{
$ErrorMessage = $_.Exception.Message
Write-Host $ErrorMessage
}
}
else
{
Write-Host "Site Doesn't exist"
}
$list.Update();

Related

get the name of the new file in powershell

#Config Variables
$SiteURL = "https://company.sharepoint.com/sites/Test-Reports"
$FolderURL= "/Shared Documents/" #Folder's Site Relative Path
$oldCount = 16
function fileOps {
Try {
#Connect to PnP Online
Connect-PnPOnline -Url $SiteURL -Interactive
#Get All Files from the Folder
$FolderItems = Get-PnPFolderItem -FolderSiteRelativeUrl $FolderURL -ItemType File
Write-host "Total Number of Files in the Folder:" $FolderItems.Count
if ($FolderItems.Count > $script:oldCount) {
Write-host "I am here"
}
$oldCount = $FolderItems.Count
ForEach($File in $FolderItems)
{
$File.Name
}
}
catch {
write-host "Error: $($_.Exception.Message)" -foregroundcolor Red
}
}
For (;;) {
fileOps
timeout 20
I am trying out powershell to get a list of files from my sharedpoint site. This lists number of the files there.I am struggling with the format though and am short on time. Once a new file is dropped, I want it to print out the name of the new file that is added and break out of this loop to call a python script. This function needs to run indefinetly.
While($TRUE)
fileOps
Continuing from my comments:
use script: scoping on your $oldCount variable inside the function, so it can update the value on that while it has been defined elsewhere
Force the $FolderItems variable to always be an array. Arrays have a .Count property, single items do not
#Config Variables
$SiteURL = "https://company.sharepoint.com/sites/Test-Reports"
$FolderURL= "/Shared Documents/" #Folder's Site Relative Path
$oldCount = 16
function fileOps {
Try {
#Connect to PnP Online
Connect-PnPOnline -Url $SiteURL -Interactive -ErrorAction Stop
#Get All Files from the Folder
# use the `#()` construct to ensure you receive an array of items
$FolderItems = #(Get-PnPFolderItem -FolderSiteRelativeUrl $FolderURL -ItemType File -ErrorAction Stop)
Write-host "Total Number of Files in the Folder:" $FolderItems.Count
# PowerShell uses `-gt` operator for Greater Than, not the `>`
if ($FolderItems.Count -gt $script:oldCount) {
Write-host "I am here"
}
# set the script-scoped variable to its new value
$script:oldCount = $FolderItems.Count
# output the file names
$FolderItems.Name
}
catch {
write-host "Error: $($_.Exception.Message)" -foregroundcolor Red
}
}

Download files from set of folders on FTP/SFTP server with WinSCP .NET assembly in PowerShell and email results

I have this PowerShell script that I'm working on. CSV file is imported to get source and destination paths. The goal is to move files from a SFTP/FTP server into a destination and send an email report.
Task scheduler will run this code every hour. And if there's a new file, as email will be sent out.
It's almost done, but two things are missing:
Check if the file already exists and Body email seems empty: Getting the following error: Cannot validate argument on parameter 'Body'. The argument is null or empty. Provide an argument that is not
null or empty, and then try the command again.
I would like some assistance on how to check if the file exists and how to get this email if a new file was dropped and copied to the destination list
$SMTPBody = ""
$SMTPMessage = #{
"SMTPServer" = ""
"From" = ""
"To" = ""
"Subject" = "New File"
}
try {
# Load WinSCP .NET assembly
Add-Type -Path "C:\Program Files (x86)\WinSCP\WinSCPnet.dll"
# Setup session options
$sessionOptions = New-Object WinSCP.SessionOptions -Property #{
Protocol = [WinSCP.Protocol]::sftp
HostName = ""
UserName = ""
Password = ""
PortNumber = "22"
FTPMode = ""
GiveUpSecurityAndAcceptAnySshHostKey = $true
}
$session = New-Object WinSCP.Session
try
{
# Connect
$session.Open($sessionOptions)
# Download files
$transferOptions = New-Object WinSCP.TransferOptions
$transferOptions.TransferMode = [WinSCP.TransferMode]::Binary
Import-Csv -Path "D:\FILESOURCE.csv" -ErrorAction Stop | foreach {
$synchronizationResult = $session.SynchronizeDirectories(
[WinSCP.SynchronizationMode]::Local, $_.Destination, $_.Source, $False)
$synchronizationResult.Check()
foreach ($download in $synchronizationResult.Downloads ) {
Write-Host "File $($download.FileName) downloaded" -ForegroundColor Green
$SMTPBody +=
"`n Files: $($download.FileName -join ', ') `n" +
"Current Location: $($_.Destination)`n"
Send-MailMessage #SMTPMessage -Body $SMTPBody
}
$transferResult =
$session.GetFiles($_.Source, $_.Destination, $False, $transferOptions)
#Find the latest downloaded file
$latestTransfer =
$transferResult.Transfers |
Sort-Object -Property #{ Expression = { (Get-Item $_.Destination).LastWriteTime }
} -Descending |Select-Object -First 1
}
if ($latestTransfer -eq $Null) {
Write-Host "No files found."
$SMTPBody += "There are no new files at the moment"
}
else
{
$lastTimestamp = (Get-Item $latestTransfer.Destination).LastWriteTime
Write-Host (
"Downloaded $($transferResult.Transfers.Count) files, " +
"latest being $($latestTransfer.FileName) with timestamp $lastTimestamp.")
$SMTPBody += "file : $($latestTransfer)"
}
Write-Host "Waiting..."
Start-Sleep -Seconds 5
}
finally
{
Send-MailMessage #SMTPMessage -Body $SMTPBody
# Disconnect, clean up
$session.Dispose()
}
}
catch
{
Write-Host "Error: $($_.Exception.Message)"
}
I believe your code has more problems than you think.
Your combination of SynchronizeDirectories and GetFiles is suspicious. You first download only the new files by SynchronizeDirectories and then you download all files by GetFiles. I do not think you want that.
On any error the .Check call will throw and you will not collect the error into your report.
You keep sending partial reports by Send-MailMessage in the foreach loop
This is my take on your problem, hoping I've understood correctly what you want to implement:
$SMTPBody = ""
Import-Csv -Path "FILESOURCE.csv" -ErrorAction Stop | foreach {
Write-Host "$($_.Source) => $($_.Destination)"
$SMTPBody += "$($_.Source) => $($_.Destination)`n"
$synchronizationResult =
$session.SynchronizeDirectories(
[WinSCP.SynchronizationMode]::Local, $_.Destination, $_.Source, $False)
$downloaded = #()
$failed = #()
$latestName = $Null
$latest = $Null
foreach ($download in $synchronizationResult.Downloads)
{
if ($download.Error -eq $Null)
{
Write-Host "File $($download.FileName) downloaded" -ForegroundColor Green
$downloaded += $download.FileName
$ts = (Get-Item $download.Destination).LastWriteTime
if ($ts -gt $latest)
{
$latestName = $download.FileName;
$latest = $ts
}
}
else
{
Write-Host "File $($download.FileName) download failed" -ForegroundColor Red
$failed += $download.FileName
}
}
if ($downloaded.Count -eq 0)
{
$SMTPBody += "No new files were downloaded`n"
}
else
{
$SMTPBody +=
"Downloaded $($downloaded.Count) files:`n" +
($downloaded -join ", ") + "`n" +
"latest being $($latestName) with timestamp $latest.`n"
}
if ($failed.Count -gt 0)
{
$SMTPBody +=
"Failed to download $($failed.Count) files:`n" +
($failed -join ", ") + "`n"
}
$SMTPBody += "`n"
}
It will give you a report like:
/source1 => C:\dest1`
Downloaded 3 files:
/source1/aaa.txt, /source1/bbb.txt, /source1/ccc.txt
latest being /source1/ccc.txt with timestamp 01/29/2020 07:49:07.
/source2 => C:\dest2
Downloaded 1 files:
/source2/aaa.txt
latest being /source2/aaa.txt with timestamp 01/29/2020 07:22:37.
Failed to download 1 files:
/source2/bbb.txt
To check and make sure the csv file exists before you process the entire thing, you can use the Test-Path,
...
if (!(Test-Path D:\FileSource.csv)) {
Write-Output "No File Found"
$SMTPBody += "There are no new files at the moment"
return; # Dont run. file not found. Exit out.
}
Import-Csv -Path "D:\FILESOURCE.csv" -ErrorAction Stop | foreach {
...
and for the Body error you are getting, it is coming from the finally loop because there are cases where $SMTPBody would be null. This will no longer be an issue because $SMTPBody will have some text when file is not found at the beginning.
Even though you are using return in the if statement to check if the file exists, finally will always get executed. Since we updated $smtpbody, your Send-MailMessage will no longer error out.
Update
If you want to check if the file you are downloading already exists, you can use the if statement like this,
foreach ($download in $synchronizationResult.Downloads ) {
if (!(Test-Path Join-Path D: $download.FileName) {
$SMTPBody += "File $($download.Filename) already exists, skipping."
continue # will go to the next download...
}
Write-Host "File $($download.FileName) downloaded" -ForegroundColor Green
...
If you do get the error regarding body, thats mostly because your script came across an exception and was sent straight over to finally statement. Finally statement sends the email with empty body because it was never set (due to exception). I would recommend using the debugger (step through) and see which step causes the exception and look into adding steps to make sure script doesnt fail.

Split Powershell script into two separate parts

I've got this script that connects to Sharepoint Online, indexes all the files and folders, downloads them all in a systematic fashion and churns out a .csv with the name of file, folders, size, path, etc.
For various reasons I've ended up in a situation where I've got all the data, but the metadata is corrupted (the .csv file aforementioned).
Unfortunately re running the whole script just for that isn't really an option, as that would require around 90 hours.
I've been trying to break the code down in order to remove the "download files" functions and just keep the part that generates the .csv, but so far without luck.
I've found the Function that seem to be in charge of it (WriteLog), but I'm struggling to separate it from the rest.
P.S. The code is not mine, I've inherited it from a developer I haven't got access to (unfortunately)
Please find the code below:
param(
[Parameter(Mandatory = $true)]
[string]$srcUrl,
[Parameter(Mandatory = $true)]
[string]$username,
[Parameter(Mandatory = $false,HelpMessage = "From Date: (dd/mm/yyyy)")]
[string]$fromDate,
[Parameter(Mandatory = $false,HelpMessage = "To Date: (dd/mm/yyyy)")]
[string]$toDate,
[Parameter(Mandatory = $true)]
[string]$folderPath,
[Parameter(Mandatory = $true)]
[string]$csvPath
) #end param
cls
#Load SharePoint CSOM Assemblies
Add-Type -Path "C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.SharePoint.Client.Runtime.dll"
$global:OutFilePath = -join ($csvPath,"\Documents.csv")
$global:OutFilePathError = -join ($csvPath,"\ErrorLog_GetDocuments.csv")
$header = "Title,Type,Parent,Name,Path,FileSize(bytes),Created,Created by,Modified,Modified by,Matterspace title,Matterspace url"
$srcLibrary = "Documents"
$securePassword = Read-Host -Prompt "Enter your password: " -AsSecureString
$credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials ($username,$securePassword)
$sUrl = [System.Uri]$srcUrl
$domainUrl = -join ("https://",$sUrl.Host)
function WriteLog
{
param(
[Parameter(Mandatory = $true)] $title,$type,$folderName,$name,$path,$fileSize,$created,$createdby,$modifed,$modifiedby,$matterspacetitle,$materspaceUrl
)
$nowTime = Get-Date -Format "dd-MMM-yy,HH:mm:ss"
$folderName = $folderName.Replace(",","|") ### sometime folder / file name has comma so replace it with something
$name = $name.Replace(",","|")
#$path = $path.Replace(",","|")
$title=[System.String]::Concat("""""""$title""""""")
$type=[System.String]::Concat("""""""$type""""""")
$folderName=[System.String]::Concat("""""""$folderName""""""")
$name=[System.String]::Concat("""""""$name""""""")
$path=[System.String]::Concat("""""""$path""""""")
$fileSize=[System.String]::Concat("""""""$fileSize""""""")
$created=[System.String]::Concat("""""""$created""""""")
$createdby=[System.String]::Concat("""""""$createdby""""""")
$modified=[System.String]::Concat("""""""$modified""""""")
$modifiedby=[System.String]::Concat("""""""$modifiedby""""""")
$matterspacetitle=[System.String]::Concat("""""""$matterspacetitle""""""")
$materspaceUrl=[System.String]::Concat("""""""$materspaceUrl""""""")
$lineContent = "$("$title"),$($type),$($folderName),$($name),$($path),$($fileSize),$($created),$($createdby),$($modified),$($modifiedby),$($matterspacetitle),$($materspaceUrl)"
Add-Content -Path $global:OutFilePath -Value "$lineContent"
}
#Function to get all files of a folder
Function Get-FilesFromFolder([Microsoft.SharePoint.Client.Folder]$Folder,$SubWeb,$MTitle)
{
Write-host -f Yellow "Processing Folder:"$Folder.ServerRelativeUrl
$folderItem = $Folder.ListItemAllFields
#$srcContext.Load($f)
$Ctx.Load($folderItem)
$Ctx.ExecuteQuery()
#Get All Files of the Folder
$Ctx.load($Folder.files)
$Ctx.ExecuteQuery()
$authorEmail = $folderItem["Author"].Title
$editorEmail = $folderItem["Editor"].Title
$filepath = $folderItem["FileDirRef"]
if([string]::IsNullOrEmpty($filepath))
{
$filepath=$Folder.ServerRelativeUrl
}
$created = $folderItem["Created"]
$modified = $folderItem["Modified"]
$title = $folderItem["Title"]
if ([string]::IsNullOrEmpty($title))
{
$title = "Not Specified"
}
#$fileSize = $fItem["File_x0020_Size"]
$fileName = $Folder.Name
#list all files in Folder
write-host $Folder.Name
$splitString=$Folder.ServerRelativeUrl -split('/')
$dirUrl="";
write-host $splitString.Length
$parentUrl=""
For($i=3; $i -le $splitString.Length;$i++)
{
if($splitString[$i] -notcontains('.'))
{
Write-Host $i
Write-Host $splitString[$i]
$dirUrl=-join($dirUrl,"\",$splitString[$i])
$parentUrl=-join($parentUrl,"\",$splitString[$i+1])
}
}
$dirPath = -join ($folderPath,$dirUrl)
WriteLog $title "Folder" $parentUrl.TrimEnd('\') $fileName $filepath 0 $created $authorEmail $modified $editorEmail $MTitle $SubWeb
write-host $dirPath
if (-not (Test-Path -Path $dirPath))
{
New-Item -ItemType directory -Path $dirPath
}
ForEach ($File in $Folder.files)
{
try{
$remarkDetail = ""
$replacedUser = ""
$fItem = $File.ListItemAllFields
#$srcContext.Load($f)
$Ctx.Load($fItem)
$Ctx.ExecuteQuery()
$authorEmail = $fItem["Author"].Email
$editorEmail = $fItem["Editor"].Email
$filepath = $fItem["FileDirRef"]
$fileSizeBytes = $fItem["File_x0020_Size"];
$fileSize = ($fileSizeBytes) / 1MB
$fileName = $fItem["FileLeafRef"]
$title = $fItem["Title"]
$filecreated = $fitem["Created"]
$fileModified = $fitem["Modified"]
$FileUrl = $fItem["FileRef"]
$Fname=$File.Name
if ([string]::IsNullOrEmpty($title))
{
$title = "Not Specified"
}
#$title,$type, $folderName,$name,$path,$fileSize,$created,$createdby,$modifed,$modifiedby,$matterspacetitle,$materspaceUrl
$dateToCompare = Get-Date (Get-Date -Date $fileModified -Format 'dd/MM/yyyy')
#Get the File Name or do something
if (($dateToCompare -ge $startDate -and $dateToCompare -le $endDate) -or ($startDate -eq $null -and $endDate -eq $null))
{
$downloadUrl = -join ($dirPath,$File.Name)
$fromfile = -join ($domainUrl,$FileUrl)
Write-Host "Downloading the file from " $fromfile -ForegroundColor Cyan
try{
$webclient = New-Object System.Net.WebClient
$webclient.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials ($username,$securePassword)
$webclient.Headers.Add("X-FORMS_BASED_AUTH_ACCEPTED","f")
$webclient.DownloadFile($fromfile,$downloadUrl)
$webclient.Dispose()
}
catch{
$ErrorMessage=$_.Exception.Message
$ErrorMessage = $ErrorMessage -replace "`t|`n|`r",""
$ErrorMessage = $ErrorMessage -replace " ;|; ",";"
$lineContent = "$($Fname),$($fromfile ),$($ErrorMessage)"
Add-Content -Path $global:OutFilePathError -Value "$lineContent"
Write-Host "Skipping the file and recalling the function" -ForegroundColor Blue
}
WriteLog $title "File" $Folder.Name $fileName $FileUrl $fileSize $created $authorEmail $modified $editorEmail $MTitle $SubWeb
Write-host -f Magenta $File.Name
}
else
{
Write-Host "Skipping the matterspace :" $title " as the matterspace was not in the date range" -ForegroundColor Blue
}
}
catch{
$ErrorMessage=$_.Exception.Message
$ErrorMessage = $ErrorMessage -replace "`t|`n|`r",""
$ErrorMessage = $ErrorMessage -replace " ;|; ",";"
$lineContent = "$($Fname),$($fromfile ),$($ErrorMessage)"
Add-Content -Path $global:OutFilePathError -Value "$lineContent"
}
}
#Recursively Call the function to get files of all folders
$Ctx.load($Folder.Folders)
$Ctx.ExecuteQuery()
#Exclude "Forms" system folder and iterate through each folder
ForEach($SubFolder in $Folder.Folders | Where {$_.Name -ne "Forms"})
{
Get-FilesFromFolder -Folder $SubFolder -SubWeb $SubWeb -Mtitle $MTitle
}
}
Function Get-SPODocLibraryFiles()
{
param
(
[Parameter(Mandatory=$true)] [string] $SiteURL,
[Parameter(Mandatory=$true)] [string] $LibraryName
)
#Setup the context
$Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$Ctx.Credentials = $credentials
$srcWeb = $Ctx.Web
$childWebs = $srcWeb.Webs
$Ctx.Load($childWebs)
$Ctx.ExecuteQuery()
foreach ($childweb in $childWebs)
{
try
{
#Get the Library and Its Root Folder
$Library=$childweb.Lists.GetByTitle($LibraryName)
$Ctx.Load($Library)
$Ctx.Load($Library.RootFolder)
$Ctx.ExecuteQuery()
#Call the function to get Files of the Root Folder
if($childweb.Url.ToLower() -notlike "*ehcontactus*" -and $childweb.Url.ToLower() -notlike "*ehfaqapp*" -and $childweb.Url.ToLower() -notlike "*ehquicksearch*" -and $childweb.Url.ToLower() -notlike "*ehsiteapps*" -and $childweb.Url.ToLower() -notlike "*ehsitelist*" -and $childweb.Url.ToLower() -notlike "*ehwelcomeapp*" -and $childweb.Url.ToLower() -notlike "*ehimageviewer*")
{
Get-FilesFromFolder -Folder $Library.RootFolder -SubWeb $childweb.Url -MTitle $childweb.Title
}
}
catch{
write-host "Skipping the matterpsace as the library does not exists" -ForegroundColor Blue
}
}
}
#Config Parameters
#$SiteURL= "https://impigerspuat.sharepoint.com/sites/ELeave/Eleave1/adminuat#impigerspuat.onmicrosoft.com"
$LibraryName="Documents"
#$securePassword = Read-Host -Prompt "Enter your password: " -AsSecureString
#Call the function to Get All Files from a document library
if (-not ([string]::IsNullOrEmpty($fromDate)))
{
$startDate = Get-Date (Get-Date -Date $fromDate -Format 'dd/MM/yyyy')
}
else
{
$startDate = $null;
}
if (-not ([string]::IsNullOrEmpty($toDate)))
{
$endDate = Get-Date (Get-Date -Date $toDate -Format 'dd/MM/yyyy')
}
else
{
$endDate = $null
}
Get-SPODocLibraryFiles -SiteURL $srcUrl -LibraryName $LibraryName
Have you tried running just that function and giving it the parameters it's requesting in the function?
Copy the code into a WriteLog.ps1 file and then call the script file with the parameters.
ie.
Writelog.ps1 $srcUrl $username $fromDate $toDate $folderPath $csvPath
Obviously, inputting data in place of the variables.
FWIW, pulling relevant pieces of code out of someone else's scripts is a great skill to practice. Everything you want to do has been done before, but you might have to break down someone else's work before it fits your exact enviornment.
Unfortunately it looks like you have to do this the old fashion way. The problem is the author is outputting to the log (csv) as the files are being downloaded. As opposed to downloading to a staging area first...
I suggest setting an early break-point in the code then stepping through to see exactly how it's flowing. That should give you a general idea, and enough info to start writing refactored code.
Reverse engineering is always tough, be prepared it will be methodical exercise so say the least.
Bad news: this will be an iterative process, not a single 'solve'. Nothing "wrong" with that code, but there are a few design choices that make this a challenge. It's not indented consistently and it weaves through all the variable assignments in slightly different ways. Looks better than most of my code, I'm just telling you what makes it a challenge.
Good news: At least that WriteLog function is separate. And it's really just adding content to the .csv file defined in this variable assigned here:
$global:OutFilePath = -join ($csvPath,"\Documents.csv")
(line 20 in my copy)
*
RECOMMENDATION: (this is an approach, just a guide to your final solution)
Take that existing code and drop it in an IDE to help you visually. The Windows Powershell ISE is adequate, but I would highly recommend VSCode.
Comment out that last line:
Get-SPODocLibraryFiles -SiteURL $srcUrl -LibraryName $LibraryName
So you can retain any of the other context from the script you actually want to keep.
Create a separate function named something like:
function Get-FilesFromLocalFolder ($localdir, $SubWeb, $MTitle)
to use instead of the existing function Get-FilesFromFolder. That way you can iterate through whatever directories you need, get the files, and assign variables to pass as parameters. Then when you call WriteLog, it will look very similar. Those last two parameters ($SubWeb, $MTitle) are passed just because WriteLog needs them. You could make them your own labels, or you could remove them and make them optional in WriteLog.
You could start by hard-coding values in each of required parameters for the function, and then run it to see if the output is working.
It will take you some iterations (agree with #Steven) and it is definitely a valuable exercise (agree with #TheIdesOfMark). :)

Check if word file is password protected in powershell

I've written a script to recursively loop through every directory, find word files and append "CONFIDENTIAL" to the footer. This worked fine until it came across an encrypted file which caused the script to hang and when I clicked cancel on the password prompt, it caused the script to crash. I've attempted to
check if the document is encrypted before opening it but the prompt still opens which crashes the script. Is there a reliable way to check if the document is password protected that will work on .doc and .docx files? I've already tried using the code in the other thread and the first two methods don't work, the third method detects every file as encrypted because it throws an exception.
Current code:
$word = New-Object -ComObject Word.Application
$word.Visible = $false
$files = Get-ChildItem -Recurse C:\temp\FooterDocuments -include *.docx,*.doc
$restricted = "CONFIDENTIAL"
foreach ($file in $files) {
$filename = $file.FullName
Write-Host $filename
try {
$document = $word.Documents.Open($filename, $null, $null, $null, "")
if($document.ProtectionType -ne -1) {
$document.Close()
Write-Host "$filename is encrypted"
continue
}
} catch {
Write-Host "$filename is encrypted"
continue
}
foreach ($section in $document.Sections) {
$footer = $section.Footers.Item(1)
$footer.Range.Characters.Last.InsertAfter("`n" + $restricted)
}
$document.Save()
$document.Close()
}
$word.Quit()
You can just use get-content.
$filelist = dir c:\tmp\*.docx
foreach ($file in $filelist) {
[pscustomobject]#{
File = $file.FullName
HasPassword = [bool]((get-content $file.FullName) -match "http://schemas.microsoft.com/office/2006/keyEncryptor/password" )
}
}
sample output:
File HasPassword
---- -----------
C:\tmp\New Microsoft Word Document (2).docx False
C:\tmp\New Microsoft Word Document.docx True

Removing an element from a library

I have a library in a list which contains a document I want to delete. This has to be done for site collections, so I decided to make a script do it.
#Set the Error Action
$ErrorActionPreference = "Stop"
Try{
$customers = $SiteURL.GetFolder
foreach ($customer in $customers){
#customer is a list that contains the library sitepages
$customerlists = $customer.List.TryGetList("Site Pages")
#correctitem is the document item that I want to remove
$correctitem = $customerlists.List.TryGetList("123")
if ($correctitem){
#delete it (havent gotten here yet)
}
}
}
catch {
Write-Host $_.Exception.Message -ForegroundColor Red
}
finally {
#Reset the Error Action to Default
$ErrorActionPreference = "Continue"
}
However, I cant get it to work. The URL works, but the customers variable, when I try to Write-Host it does not display anything.
Any ideas?
If you want to delete a document from a document library, the PowerShell script below for your reference:
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
$site = new-object Microsoft.SharePoint.SPSite("http://sharepoint-site-url")
$web = $site.openweb()
$list=$web.Lists["Site Pages"]
$listItems = $list.Items
$listItemsTotal = $listItems.Count
Write-Host $listItemsTotal
for ($x=$listItemsTotal-1;$x -ge 0; $x--)
{
if($listItems[$x].name.Contains("123")) # file refers to the name of the document
{
Write-Host("DELETED: " + $listItems[$x].name)
$listItems[$x].Delete()
}
}