My Tool: Using Gulp and Powershell to Automate File Uploading and Approval for SharePoint 2010
Usges
Automate uploading all changed files to SharePoint
c:\dev\wan\MyProject\gulp defaultor
c:\dev\wan\MyProject\gulp spdefault
Automate appoving all files in SharePoint
c:\dev\wan\MyProject\gulp approveallAutomate checking in all files in SharePoint
c:\dev\wan\MyProject\gulp checkinallAutomate checking out all files in SharePoint
c:\dev\wan\MyProject\gulp checkoutallNote
- Please ensure Powershell version must be at least 4 ! ($PSVersionTable.PSVersion)
- To Map Network Drive, WebDAV must be installed (Server Feature/Desktop Experience/Restart Server, enable WebClient service)
- if the mapped drive Z: is not recognized in powershell or command line, please "net use Z: http://pre.dev.com" instead
- Please login to Z: first else copying will fail due to no access
Content of c:/dev/wan/MyProject/gulpfile.js
// https://www.spdavid.com/use-gulp-and-npm-to-automate-2/ // For SP2013 and SP 2016: https://www.definitivelogic.com/2017/02/21/legacy-sharepoint-gulp-robocopy/ // For SP2010: https://www.definitivelogic.com/2017/02/28/legacy-sharepoint-development-2007-and-2010-gulp-and-robocopy/ // http://thomasdaly.net/2018/01/05/sharepoint-quick-deploy-build-process-using-node-gulp-sp-save-part-2/ var gulp = require('gulp') var spsave = require('gulp-spsave') var watch = require('gulp-watch') var cached = require('gulp-cached'); var robocopy = require('robocopy'); var powershell = require('node-powershell'); var sourceDir = "c:/dev/wan/MyProject"; var mapDrive = "Z:"; var rootSiteUrl = "http://pre.dev.com"; var filelist = [ { files: ["EServices.txt"], // source files, separated by "," subSiteUrl: "", // destination subsite url ("" means root site) folder: "/Pages", // destination folder within this subsite (related to subSiteUrl) copy: true // true (default): copy these files; false: don't copy }, { files: ["EServices.js"], subSiteUrl: "", folder: "/Pages/EServices/js", copy: true }, { files: ["jquery.smartWizard.fix.js"], subSiteUrl: "", folder: "/Pages/EServices/js", copy: true }, { files: ["jquery.smartWizard.custom.js"], subSiteUrl: "", folder: "/Pages/EServices/js", copy: true }, { files: ["smart_wizard_theme_dots_custom.css"], subSiteUrl: "", folder: "/Pages/EServices/css", copy: true }, { files: ["EServices.css"], subSiteUrl: "", folder: "/Pages/EServices/css", copy: true }, { files: ["Licence.txt"], subSiteUrl: "", folder: "/Pages/EServices", copy: true }, { files: ["Application.txt"], subSiteUrl: "/Applications", folder: "/Pages", copy: true }, { files: ["Subsidy.txt", "Calculator.txt"], subSiteUrl: "/Services/Subsidy", folder: "/Pages", copy: true } ]; function copyall(filelist) { // files must be checked out before being overwritten spfileversioningall(filelist, "CheckOut"); for (var i=0; i< filelist.length; i++) { if (typeof filelist[i].copy == typeof udnefined || filelist[i].copy) { robocopy({ source: sourceDir, destination: mapDrive + filelist[i].subSiteUrl + filelist[i].folder, files: filelist[i].files, copy: { info: 'DT' }, retry: { count: 1, wait: 3 } }) } } } function spfileversioningall(filelist, func) { for (var i=0; i< filelist.length; i++) { if (typeof filelist[i].copy == typeof udnefined || filelist[i].copy) { for (var j=0; j < filelist[i].files.length; j++) { spfileversioning(func, rootSiteUrl + filelist[i].subSiteUrl, filelist[i].subSiteUrl + filelist[i].folder + "/" + filelist[i].files[j]); } } } } function spfileversioning(func, siteUrl, fileServerRelativeUrl) { let ps = new powershell({ executionPolicy: 'Bypass', noProfile: true }); ps.addCommand('./SPFileVersioning.ps1', [ {"function": func}, {"siteUrl": siteUrl}, {"fileServerRelativeUrl": fileServerRelativeUrl} ]) ps.invoke() .then(output => { console.log(output); ps.dispose(); }) .catch(err => { console.log(err); ps.dispose(); }); } gulp.task('spdefault', function() { // runs the spsave gulp command on only files the have // changed in the cached files return gulp.src(sourceDir + "/*") .pipe(cached('spFiles')) .pipe(copyall(filelist)); }); gulp.task('default', function() { // create an initial in-memory cache of files gulp.src(sourceDir + "/*") .pipe(cached('spFiles')); // watch the src folder for any changes of the files gulp.watch([sourceDir + "/*"], ['spdefault']); }); gulp.task('approveall', function() { spfileversioningall(filelist, "approve"); }); gulp.task('checkinall', function() { spfileversioningall(filelist, "checkin"); }); gulp.task('checkoutall', function() { spfileversioningall(filelist, "checkout"); });
Content of c:/dev/wan/MyProject/SPFileVersioning.ps1
<# https://bramdejager.wordpress.com/2013/08/02/using-csom-and-powershell-to-query-sharepoint-online-or-on-premise/ https://stackoverflow.com/questions/36585936/sharepoint-csom-powershell-does-not-return-web-folders-property/36671910 http://www.sharepointdiary.com/2016/10/sharepoint-online-how-to-check-in-document-using-powershell.html https://wprogramming.wordpress.com/2011/07/18/dynamic-function-and-variable-access-in-powershell/ https://social.technet.microsoft.com/wiki/contents/articles/26436.how-to-create-and-use-enums-in-powershell.aspx #> param( [string] $function = "approve", [string] $siteUrl = "http://pre.dev.com", [string] $fileServerRelativeUrl = "/Pages/EServices/js/jquery.smartWizard.fix.js" ) #Add-PSSnapin Microsoft.SharePoint.Powershell #-ErrorAction SilentlyContinue #We will use CSOM to access SharePoint folders Add-Type -Path "C:\Program Files\Common Files\microsoft shared\SharePoint Client\Microsoft.SharePoint.Client.dll" Add-Type -Path "C:\Program Files\Common Files\microsoft shared\SharePoint Client\Microsoft.SharePoint.Client.Runtime.dll" Add-Type -TypeDefinition @" public enum SPModerationStatusType { Approved, Denied, Pending, Draft, Scheduled } "@ Function CheckIn($siteUrl, $fileServerRelativeUrl) { <# To check in a file in root site: .\SPFileVersioning.ps1 -function CheckIn -siteUrl "http://pre.dev.com" -fileServerRelativeUrl /Pages/EServices/js/Test.html To check in a file in a sub site: ./SPFileVersioning.ps1 -function CheckIn -siteUrl http://pre.dev.com/Services/Subsidy -fileServerRelativeUrl /Services/Subsidy/Calculator.txt #> $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($siteUrl) Try { $file = $ctx.Web.GetFileByServerRelativeUrl($fileServerRelativeUrl) $ctx.Load($file) $ctx.ExecuteQuery() If($file.CheckOutType -eq "None") { write-host "$($file.Name) is not checked out and no need to be checked in!" -f Red } else { # MajorCheckIn is equivalent to Publish("") $file.CheckIn("",[Microsoft.SharePoint.Client.CheckinType]::MajorCheckIn) $ctx.ExecuteQuery() write-host "$($file.Name) has been checked-in successfully!" -f Green } } Catch { write-host -f Red "Error checking-in $($file.Name)!" $_.Exception.Message } } Function CheckOut($siteUrl, $fileServerRelativeUrl) { $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($siteUrl) Try { $file = $ctx.Web.GetFileByServerRelativeUrl($fileServerRelativeUrl) $ctx.Load($file) $ctx.ExecuteQuery() #check if the file is already checked out If($file.CheckOutType -ne "None") { write-host "$($file.Name) is already checked out!" -f Yellow } else { $file.CheckOut() $ctx.ExecuteQuery() write-host "$($file.Name) has been checked out successfully!" -f Green } } Catch { write-host -f Red "Error checking out $($file.Name)!" + $_.Exception.Message } } Function Approve($siteUrl, $fileServerRelativeUrl) { $ctx = New-Object Microsoft.SharePoint.Client.ClientContext($siteUrl) Try { $file = $ctx.web.GetFileByServerRelativeUrl($fileServerRelativeUrl) $item = $file.ListItemAllFields $ctx.Load($file) $ctx.Load($item) $ctx.ExecuteQuery() # CSOM ListItem class does not have a ModerationInformation property! if( $item["_ModerationStatus"] -eq [SPModerationStatusType]::Approved) { write-host "$($file.Name) is already approved and no need to be re-approved" -f Green } else { if( $item["_ModerationStatus"] -eq [SPModerationStatusType]::Draft) { CheckIn -siteUrl $siteUrl -fileServerRelativeUrl $fileServerRelativeUrl } # must re-read $item to prevent error:"Version conflict." $ctx.Load($item) $ctx.ExecuteQuery() $item["_ModerationStatus"] = [Convert]::ToInt32([SPModerationStatusType]::Approved); $item.Update(); $ctx.ExecuteQuery() write-host "$($file.Name) has been approved successfully!" -f Green } } Catch { write-host -f Red "Error approving $($file.Name)!" + $_.Exception.Message } } & $function -siteUrl $siteUrl -fileServerRelativeUrl $fileServerRelativeUrl
Comments
Post a Comment