Monthly Archives: June 2015

Microsoft wants to hear YOU! UserVoice

The below links are a great way to provide feedback for the Microsoft future roadmap, research & development, and cloud first releases.   Please give feedback and help the community steer in the right direction.   Cheers!   shades_smile

 

 

 

http://aspnet.uservoice.com
http://bingads.uservoice.com
http://microsoftvisio.uservoice.com
http://msaccess.uservoice.com
http://office365.uservoice.com
http://office365video.uservoice.com
http://officeforms.uservoice.com
http://officemix.uservoice.com
http://officespdev.uservoice.com
http://onedrive.uservoice.com
http://onenote.uservoice.com
http://owa.uservoice.com
http://powerpoint.uservoice.com
http://sharepoint.uservoice.com
http://sway.uservoice.com
http://visualstudio.uservoice.com
http://xbox.uservoice.com
http://binglistens.uservoice.com
http://excel.uservoice.com
http://systemcentervmm.uservoice.com
http://word.uservoice.com

Post to Newsfeed on behalf of another user (Server Object Model)

The below code will post to Newsfeed for any user account you specify.   Activity appears the same as if the user manually posted.   This could be helpful for populating Newsfeed from external activity, custom event receivers, workflow, and other developer sources.   Enjoy!  shades_smile

 

Screenshot

image

 

Code

using Microsoft.Office.Server.Social;
using Microsoft.Office.Server.UserProfiles;
using Microsoft.SharePoint;
using System;
using System.Text;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            // Config
            string siteUrl = "http://mysite";
            string login = "i:0#.w|domain\\user";
            using (SPSite site = new SPSite(siteUrl))
            {
                // Context
                SPUser user = site.RootWeb.SiteUsers[login];
                SPUserToken token = user.UserToken;
                SPServiceContext ctx = SPServiceContext.GetContext(site);
                using (new SPServiceContextScope(ctx))
                {
                    // Init
                    UserProfileManager upm = new UserProfileManager(ctx);
                    UserProfile prof = upm.GetUserProfile(user.LoginName);
                    SPSocialFeedManager mgr = new SPSocialFeedManager(prof, ctx, token);
                    SPSocialPostCreationData post = new SPSocialPostCreationData();
                    // Text
                    post.ContentText = "hello world, look at {0}!";
                    post.UpdateStatusText = true;
                    // Link
                    SPSocialDataItem [] link = new SPSocialDataItem [1];
                    link[0] = new SPSocialDataItem();
                    link[0].ItemType = SPSocialDataItemType.Link;
                    link[0].Text = "My Cool Link";
                    link[0].Uri = new Uri("http://www.google.com");
                    post.ContentItems = link;
                    // Save
                    SPSocialThread thread = mgr.CreatePost(null, post);
                }
            }
        }
    }
}

 

References

Custom Security Roles

Contributor is often too generic to match business needs.   Below are 4 custom security roles with more granular purpose.   Running the below PowerShell will create the roles (if missing) for a given web URL. 

Enjoy!  shades_smile

 

  • NoDelete = Contribute without delete
  • AddOnly  = Contribute without delete or edit
  • EditOnly = Contribute without add or delete
  • NoEdit   = Contribute without edit

 

# #############################################################################
# NAME:		AddCustomRoles.ps1
#
# COMMENT:  This script creates two Custom Access levels for
#			a given SharePoint URL.
#
#			* NoDelete = Contribute without delete
#			* AddOnly  = Contribute without delete or edit
#			* EditOnly = Contribute without add or delete
#			* NoEdit   = Contribute without edit
#
# REQUIRE:  Permission to unlock account
# USAGE:    .\AddCustomRoles.ps1 http://sharepoint/sites/team
#
# #############################################################################
[CmdletBinding()]
Param(
	[Parameter(Mandatory=$True,Position=1)]
	[string]$url
)
Write-Host "Opening $url ... " 
$web = Get-SPWeb $url
Write-Host "OK" -ForegroundColor Green
#### CREATE NODELETE
$nd = $web.RoleDefinitions |? {$_.Name -eq "NoDelete"}
if ($nd) {
	Write-Host "Found NoDelete" -ForegroundColor Green
} else {
	Write-Host "Missing NoDelete" 
	Write-Host "Adding NoDelete ..." 
	$noDeleteRole = New-Object "Microsoft.SharePoint.SPRoleDefinition"
	$noDeleteRole.Name = "NoDelete"
	$noDeleteRole.Description = "Can view, add, and update list items and documents."
	$noDeleteRole.BasePermissions = "AddAndCustomizePages,AddDelPrivateWebParts,AddListItems,BrowseDirectories,BrowseUserInfo,CreateAlerts,EditListItems,EditMyUserInfo,ManagePersonalViews,Open,OpenItems,UpdatePersonalWebParts,UseClientIntegration,UseRemoteAPIs,ViewFormPages,ViewListItems,ViewPages,ViewVersions"
	$web.RoleDefinitions.Add($noDeleteRole)
	Write-Host "OK" -ForegroundColor Green
}
#### CREATE ADDONLY 
$ao = $web.RoleDefinitions |? {$_.Name -eq "AddOnly"}
if ($ao) {
	Write-Host "Found AddOnly" -ForegroundColor Green
} else {
	Write-Host "Missing AddOnly" 
	Write-Host "Adding AddOnly ..." 
	$addOnlyRole = New-Object "Microsoft.SharePoint.SPRoleDefinition"
	$addOnlyRole.Name = "AddOnly"
	$addOnlyRole.Description = "Can view and add items and documents."
	$addOnlyRole.BasePermissions = "AddAndCustomizePages,AddDelPrivateWebParts,AddListItems,BrowseDirectories,BrowseUserInfo,CreateAlerts,EditMyUserInfo,ManagePersonalViews,Open,OpenItems,UpdatePersonalWebParts,UseClientIntegration,UseRemoteAPIs,ViewFormPages,ViewListItems,ViewPages,ViewVersions"
	$web.RoleDefinitions.Add($addOnlyRole)
	Write-Host "OK" -ForegroundColor Green
}

#### CREATE EDITONLY 
$eo = $web.RoleDefinitions |? {$_.Name -eq "EditOnly"}
if ($eo) {
	Write-Host "Found EditOnly" -ForegroundColor Green
} else {
	Write-Host "Missing EditOnly"
	Write-Host "Adding EditOnly ..." 
	$EditOnlyRole = New-Object "Microsoft.SharePoint.SPRoleDefinition"
	$EditOnlyRole.Name = "EditOnly"
	$EditOnlyRole.Description = "Can view, and update list items and documents."
	$EditOnlyRole.BasePermissions = "AddAndCustomizePages,AddDelPrivateWebParts,BrowseDirectories,BrowseUserInfo,CreateAlerts,EditMyUserInfo,ManagePersonalViews,Open,OpenItems,UpdatePersonalWebParts,UseClientIntegration,UseRemoteAPIs,ViewFormPages,ViewListItems,ViewPages,ViewVersions"
	$web.RoleDefinitions.Add($EditOnlyRole)
	Write-Host "OK" -ForegroundColor Green
}

#### CREATE NOEDIT 
$ne = $web.RoleDefinitions |? {$_.Name -eq "NoEdit"}
if ($ne) {
	Write-Host "Found NoEdit" -ForegroundColor Green
} else {
	Write-Host "Missing NoEdit"
	Write-Host "Adding NoEdit ..." 
	$NoEditRole = New-Object "Microsoft.SharePoint.SPRoleDefinition"
	$NoEditRole.Name = "NoEdit"
	$NoEditRole.Description = "Can add, view and delete list items and documents."
	$NoEditRole.BasePermissions = "AddAndCustomizePages,AddDelPrivateWebParts,AddListItems,BrowseDirectories,BrowseUserInfo,CreateAlerts,DeleteListItems,DeleteVersions,EditMyUserInfo,ManagePersonalViews,Open,OpenItems,UpdatePersonalWebParts,UseClientIntegration,UseRemoteAPIs,ViewFormPages,ViewListItems,ViewPages,ViewVersions"
	$web.RoleDefinitions.Add($NoEditRole)
	Write-Host "OK" -ForegroundColor Green
}

Rename MySite “Blog” for findability

SharePoint names the blog created in a personal site “Blog.”  At scale this is confusing because everyone’s blog has exactly the same title (“Blog”).

The below PowerShell will rename to “{FirstName LastName} – Blog” for a more user friendly experience across search results, follow site recommendations, and site directory.

Cheers!  shades_smile

#get all personal site blogs
$webs = Get-SPSite -Limit All |? {$_.RootWeb.WebTemplate -eq "SPSPERS"} | Get-SPWeb -Filter {$_.Template -eq "BLOG"} -Limit All
foreach ($w in $webs) {
	#progress display
	$w.Url
	
	#filter
	if ($w.Title -eq "Blog") {
		#AD lookup
		$splits = $w.Site.Url.Split("/")
		$login = $splits[$splits.length - 1]
		$user = Get-ADUser $login
		$name = $user.Name
		$title = "Blog - $name"
		
		#save
		$w.title = $title
		$w.Update()
		$w.Title
	}
}

Robocopy – My Favorite Switches

Did you know Robocopy has 85 command line switches?  Wow!  Below is my favorite switch syntax.   When I open CMD to transfer files this is the default starting point.   Wanted to share in case this helps others.  Cheers!  shades_smile

 

CMD Favorite Switches

/MIR /XX /Z /W:0 /R:0 /TEE /ETA /L

 

CMD Full Example

ROBOCOPY C:\SRC C:\DEST *.EXT /MIR /XX /Z /W:0 /R:0 /TEE /ETA /L

 

All 85 Robocopy Switches:  http://ss64.com/nt/robocopy.html

 

                /S : Copy Subfolders.
                /E : Copy Subfolders, including Empty Subfolders.
 /COPY:copyflag[s] : What to COPY (default is /COPY:DAT)
              /SEC : Copy files with SECurity (equivalent to /COPY:DATS).
          /DCOPY:T : Copy Directory Timestamps.
          /COPYALL : Copy ALL file info (equivalent to /COPY:DATSOU).
           /NOCOPY : Copy NO file info (useful with /PURGE).
                /A : Copy only files with the Archive attribute set.
                /M : like /A, but remove Archive attribute from source files.
            /LEV:n : Only copy the top n LEVels of the source tree.
         /MAXAGE:n : MAXimum file AGE - exclude files older than n days/date.
         /MINAGE:n : MINimum file AGE - exclude files newer than n days/date.
              /FFT : Assume FAT File Times (2-second date/time granularity).
              /256 : Turn off very long path (> 256 characters) support.
                /L : List only - don’t copy, timestamp or delete any files.
              /MOV : MOVe files (delete from source after copying).
             /MOVE : Move files and dirs (delete from source after copying).
               /sl : Copy symbolic links instead of the target.
                /Z : Copy files in restartable mode (survive network glitch).
                /B : Copy files in Backup mode.
               /ZB : Use restartable mode; if access denied use Backup mode.
            /IPG:n : Inter-Packet Gap (ms), to free bandwidth on slow lines.
              /R:n : Number of Retries on failed copies - default is 1 million.
              /W:n : Wait time between retries - default is 30 seconds.
              /REG : Save /R:n and /W:n in the Registry as default settings.
              /TBD : Wait for sharenames To Be Defined (retry error 67).
    /A+:[RASHCNET] : Set file Attribute(s) on destination files + add.
    /A-:[RASHCNET] : UnSet file Attribute(s) on destination files - remove.
              /FAT : Create destination files using 8.3 FAT file names only.
           /CREATE : CREATE directory tree structure + zero-length files only.
              /DST : Compensate for one-hour DST time differences.
            /PURGE : Delete dest files/folders that no longer exist in source.
              /MIR : MIRror a directory tree - equivalent to /PURGE plus all subfolders (/E)
                /L : List only - don’t copy, timestamp or delete any files.
               /NP : No Progress - don’t display % copied.
          /unicode : Display the status output as Unicode text.  ##
         /LOG:file : Output status to LOG file (overwrite existing log).
      /UNILOG:file : Output status to Unicode Log file (overwrite)
        /LOG+:file : Output status to LOG file (append to existing log).
     /UNILOG+:file : Output status to Unicode Log file (append)
               /TS : Include Source file Time Stamps in the output.
               /FP : Include Full Pathname of files in the output.
               /NS : No Size - don’t log file sizes.
               /NC : No Class - don’t log file classes.
              /NFL : No File List - don’t log file names.
              /NDL : No Directory List - don’t log directory names.
              /TEE : Output to console window, as well as the log file.
              /NJH : No Job Header.
              /NJS : No Job Summary.
            /MON:n : MONitor source; run again when more than n changes seen.
            /MOT:m : MOnitor source; run again in m minutes Time, if changed.
     /RH:hhmm-hhmm : Run Hours - times when new copies can be started.
               /PF : Check run hours on a Per File (not per pass) basis.
      /JOB:jobname : Take parameters from the named JOB file.
     /SAVE:jobname : SAVE parameters to the named job file
             /QUIT : QUIT after processing command line (to view parameters). 
             /NOSD : NO Source Directory is specified.
             /NODD : NO Destination Directory is specified.
               /IF : Include the following Files.
           /EFSRAW : Copy any encrypted files using EFS RAW mode.
           /MT[:n] : Multithreaded copying, n = no. of threads to use (1-128) ##
           /SECFIX : FIX file SECurity on all files, even skipped files.
           /TIMFIX : FIX file TIMes on all files, even skipped files.
               /XO : eXclude Older - if destination file exists and is the same date
         /XC | /XN : eXclude Changed | Newer files
               /XL : eXclude "Lonely" files and dirs (present in source but not destination)
               /XX : eXclude "eXtra" files and dirs (present in destination but not source)
/XF file [file]... : eXclude Files matching given names/paths/wildcards.
/XD dirs [dirs]... : eXclude Directories matching given names/paths.
   /IA:[RASHCNETO] : Include files with any of the given Attributes
   /XA:[RASHCNETO] : eXclude files with any of the given Attributes
               /IS : Include Same, overwrite files even if they are already the same.
               /IT : Include Tweaked files.
               /XJ : eXclude Junction points. (normally included by default).
              /XJD : Exclude junction points for directories. ##
              /XJF : Exclude junction points for files.      ##
            /MAX:n : MAXimum file size - exclude files bigger than n bytes.
            /MIN:n : MINimum file size - exclude files smaller than n bytes.
         /MAXLAD:n : MAXimum Last Access Date - exclude files unused since n.
         /MINLAD:n : MINimum Last Access Date - exclude files used since n.
            /BYTES : Print sizes as bytes.
                /X : Report all eXtra files, not just those selected & copied.
                /V : Produce Verbose output log, showing skipped files.
              /ETA : Show Estimated Time of Arrival of copied files.
            /DEBUG : Show debug volume information (undocumented)

What’s in that patch? SharePoint 2013 – Jun 2015 CU

Ever wondered what fixes are inside of a given CU?   Please see attached PDF with full detail.

I wanted a new format for easy reading.   Show management and make the business case for why downtime should be taken to apply CUs.

 

As much time as I spend patching SharePoint even I never really dig into KB article fix detail.   However, this makes it easier to see everything without obscure click from one Microsoft article to the next buried layers deep.  If you found this helpful, please leave a comment.    shades_smile_thumb_thumb_thumb

 

Whats in that patch – SharePoint 2013 – Jun 2015 CU.PDF

Learn Angular!

I wanted to share the links below for learning AngularJS.  Great way to code less AND get higher quality apps.   Dual win for developer productivity.  Enjoy!   shades_smile

 

 

Media

People

Code

Tools

 

 

* diagram from http://weblogs.asp.net/dwahlin/video-tutorial-angularjs-fundamentals-in-60-ish-minutes

AngularJS – $http default JSON headers

The below JavaScript will change $http default headers to be JSON ready for SharePoint REST APIs.  This is handy when sending GET/POST to SharePoint 2013 so we don’t need to repeat headers on each individual call.   Enjoy!  shades_smile

//namespace
var namespace = namespace || {};
//NG-controller
namespace.myCtl = function ($scope, $mySvc) {
    //viewmodel
    var vm = $scope;
};
//NG-service
namespace.mySvc = function ($q, $http) {
	$http.defaults.headers.common['Accept'] = 'application/json;odata=verbose';
	
    //User Profile - me
    this.getMe = function () {
        return $http.get('/_api/SP.UserProfiles.PeopleManager/GetMyProperties');
    };
    //User Profile - users
    this.getUser = function (login) {
		var url = '/_api/SP.UserProfiles.PeopleManager/GetPropertiesFor(accountName=@v)?@v=\'domain\\' + login + '\'';
        return $http.get(url);
    };
};
//NG-module
angular.module('myApp', [])
	.controller('myCtl', namespace.myCtl)
	.service('$mySvc', namespace.mySvc)
	.run(function () {
		//prepare GUI
	});
Return to Top ▲Return to Top ▲