Martin Bodocky

No less, no more. Just live between code.

Monthly Archives: February 2012

Check-Names before loading files to SharePoint

SharePoint has a few issues with the file and folder names containing illegal characters
and postfix. I have describe it here on my
previous post
. And now I create PowerShell script which can say you which
items are good and which you or system must rename.

functionglobal:Check-Names ($Path, [switch]$Fix, [switch]$Verbose)

{

    if([System.String]::IsNullOrEmpty($Path)) { $Path=$PWD }

    Write-Host Checkingfiles in $Path, please wait…

    #Get all files and folders under the path specified

    $items= Get-ChildItem -Path $Path -Recurse

    $folders= New-Object -TypeName “System.Collections.ArrayList”

    foreach ($item in $items)

    {

    #Check if the item is a file or a folder

    if ($item.PSIsContainer)

    {

       $v=$folders.Add($item);

       continue;

    }

    CheckInternal($item.FullName,$Fix,“File”);

    }

 

#We need start change names of folders from deeply locations

$folders.Reverse();

foreach($item in $folders)

{

CheckInternal($item.FullName,$Fix,“Folder”);

}

}

function CheckInternal($paramValues)

{

#Loading information from properties

[string]$Path=$paramValues[0];

[bool]$Fix=$paramValues[1];

[string]$type=$paramValues[2];

$item= Get-Item $Path

#Report item has been found if verbose mode is selected

    if($Verbose) {

       Write-Host Found a $type called $item.FullName

    }

#Check if item name is 128 characters or more in length

    if($item.Name.Length -gt 127)

    {

       Write-Host $type $item.Name is 128 characters or over and will need to be truncated -ForegroundColor Red

    }

    else

    {

       $illegalChars=‘[\/:*?"<>|#{}%~&]‘

       filter Matches($illegalChars)

       {

       $item.Name | Select-String -AllMatches
       $illegalChars |

       Select-Object -ExpandProperty Matches

       Select-Object -ExpandProperty Values

       }

   #Replace illegal characters with legal characters where found

   [string]$newFileName=$item.Name

   Matches $illegalChars | ForEach-Object {

      Write-Host $type $item.FullName has the illegal character $_.Value -ForegroundColor Red

      #These characters may be used on the file system but not SharePoint

      if($_.Value -match“&”) { $newFileName= ($newFileName -replace “&”, “and”)}

      if($_.Value -match“{“) { $newFileName= ($newFileName -replace “{“, “(“)}

      if($_.Value -match“}”) { $newFileName= ($newFileName -replace “}”, “)”)}

      if($_.Value -match“~”) { $newFileName= ($newFileName -replace “~”, “-”)}

      if($_.Value -match“#”) { $newFileName= ($newFileName -replace “#”, “hash”)}

      if($_.Value -match“%”) { $newFileName= ($newFileName -replace “%”, “per.”)}

}

   #Check for start, end and double periods

   if($newFileName.StartsWith(“.”)) { Write-Host $type $item.FullName starts witha period -ForegroundColor Red }

   while($newFileName.StartsWith(“.”)) { $newFileName=$newFileName.TrimStart(“.”) }

   if($newFileName.EndsWith(“.”)) { Write-Host $type $item.FullName ends witha period -ForegroundColor Red }

   while($newFileName.EndsWith(“.”)) { $newFileName=$newFileName.TrimEnd(“.”) }

   if($newFileName.Contains(“..”)) { Write-Host $type $item.FullName contains double periods -ForegroundColor Red }

   while($newFileName.Contains(“..”)) { $newFileName=$newFileName.Replace(“..”, “.”) }

#Check names for ending with forbidden strings only for folders

if($type -eq “Folder”)

{

[array]$forbiddens=“_files”,“_fichiers”,“_bestanden”,“_file”,“_archivos”,

“_tiedostot”,“_pliki”,“_soubory”,“_elemei”,“_ficheiros”,“_arquivos”,“_dosyalar”,

“_datoteke”,“_fitxers”,“_failid”,“_fails”,“_bylos”,“_fajlovi”,“_fitxategiak”,“.files”,“-Dateien”,“-files”

foreach($f in $forbiddens)

{

if($newFileName.EndsWith($f))

{

Write-Host $item.FullName contains forbidden string $f -ForegroundColor Red

$newFileName =$newFileName+“_”

}

}

}

   #Fix file and folder names if found and the Fix switch is specified

   if(($newFileName -ne $item.Name) -and ($Fix))

   {

     $item.Refresh();

     Rename-Item $item.FullName -NewName ($newFileName) -Force

     Write-Host $type $item.Name has been changed to $newFileName -ForegroundColor Green

   }

}

}

For test purpose I create folder contains items with illegal and legal names. Location
test files.


Execute “Check-Names” without parameters.


Execute “Check-Names” with parameter “-Verbose”, it’s tracking all diagnosed files.


Finally we execute “Check-Names” with parameter “-Fix” which rename all illegal
names of files or folders.


Happy Coding :)

Allow SharePoint Designer via PowerShell

Hi guys,

 

Now I’m working on governance changes and I have run into problem with users who
tried

change their site via SharePoint Designer that’s not according for governance. I
produce a script which disabled or enabled SharePoint Designer per each site collection.

 

function global:Allow-SPDesigner ([switch]$Disabled)

{

$sites = Get-SPSite -Limit ALL

foreach($site in $sites)

{

if($Disabled)

{

$site.AllowDesigner = $false

Write-Host $site.Url Change Setting to Off -ForegroundColor Red

}

else

{

$site.AllowDesigner = $true

Write-Host $site.Url Change Setting to ON -ForegroundColor Green

}

}

}

 

I hope it helps :)

Happy SharePointing !

Generic Pair C#

When you are SharePoint developer you don’t have functionality from .Net 4 such
Tuple object.
Presumably, you are not happy as me with it. I designed my own pair object with
using and I’m happy to share that.

 

///<summary>

/// CLass cover functionality as related two values with different or same type

///</summary>

///<typeparam name=”T”>Type of first value</typeparam>

///<typeparam name=”U”>Type of second value</typeparam>

[Serializable]

public class Pair<T,U>

{

#region
Properties

public T First { get; set; }

public U Second { get; set; }

#endregion

 

#region Ctors

///<summary>

/// Empty Constructor

///</summary>

public Pair() { }

///<summary>

/// Public building constructor

///</summary>

///<param name=”first”>First value</param>

///<param name=”second”>Second value</param>

public Pair(T first, U second)

{

First = first;

Second = second;

}

#endregion

#region
Override methods

///<summary>

/// Generate Object Hash code

///</summary>

///<returns>hash code</returns>

public override int GetHashCode()

{

return (First != null ? First.GetHashCode() : 0) + 29 * (Second != null ? Second.GetHashCode() : 0);

}

 

///<summary>

/// Generate string representation

///</summary>

///<returns></returns>

public override string ToString()

{

return string.Format(“First: {0}, Second: {1}”, this.First,  this.Second);

}

#endregion

 

#region
Static methods

///<summary>

/// Convert dictionary to list of paired objects

///</summary>

///<param name=”dictionary”>Input directory</param>

///<returns>List of pairs</returns>

public static List<Pair<T, U>> DictionaryToList(IDictionary<T,U> dictionary)

{

List<Pair<T, U>> list = new List<Pair<T,U>>();

if (dictionary != null)

{

foreach (KeyValuePair<T, U> pair in dictionary)

    list.Add(new Pair<T, U>(pair.Key, pair.Value));

}

return list;

}

///<summary>

/// Convert list of pairs to dictionary

///</summary>

///<param name=”list”>Input lis of pairs</param>

///<returns>dictionary of pairs objects</returns>

public static Dictionary<T,U> ListToDictionary(IList<Pair<T,U>> list)

{

Dictionary<T,U> dictionary = new Dictionary<T, U>();

try

{

if (list != null)

{

foreach(Pair<T, U> pair in list)

  dictionary.Add(pair.First, pair.Second);

}

}

catch (ArgumentException ex)

{

throw new Exception(“If key’s value already exists, use fucntion ListToDictionaryDimension.”, ex);

}

return dictionary;

}

///<summary>

/// Convert list of pairs to dictionary avoiding duplicates with key values

///</summary>

///<param name=”list”>List of pairs</param>

///<returns>Dictionary of pairs</returns>

public static Dictionary<T,List<U>> ListToDictionaryDimension(IList<Pair<T,U>> list)

{

Dictionary<T,List<U>> dictionary = new Dictionary<T, List<U>>();

if (list != null)

{

foreach(Pair<T, U> pair in list)

{

List<U> listOfValues = null;

if (!dictionary.TryGetValue(pair.First,out listOfValues))

{

listOfValues = new List<U>();

dictionary.Add(pair.First, listOfValues);

}

listOfValues.Add(pair.Second);

}

}

return dictionary;

}

///<summary>

/// Compare operator

///</summary>

///<param name=”p1″>First pair</param>

///<param name=”p2″>Second operator</param>

///<returns>result of comaprision</returns>

public static bool operator ==(Pair<T, U> p1, Pair<T, U> p2)

{

if (Equals(p1, null) && Equals(p2, null)) return true;

if (Equals(p1, null) || Equals(p2, null)) return false;

return Equals(p1.First, p2.First) && Equals(p1.Second, p2.Second);

}

///<summary>

/// Inverse compare operator

///</summary>

///<param name=”p1″>First pair</param>

///<param name=”p2″>Second operator</param>

///<returns>result of comaprision</returns>

public static bool operator !=(Pair<T, U> p1, Pair<T, U> p2)

{

if (Equals(p1, null) && Equals(p2, null)) return true;

if (Equals(p1, null) || Equals(p2, null)) return false;

return !(Equals(p1.First, p2.First) && Equals(p1.Second, p2.Second));

}

#endregion

}

 

And using:

 

Pair<int, int> p1 = new Pair<int, int>(10, 12);

Pair<int, int> p2 = new Pair<int, int>(10, 11);

if (p1 == p2)

Console.WriteLine(“P1 is not equal to P2″);

if (p1 != p2)

Console.WriteLine(“P1 is not equal to P2″);

 

Dictionary<int, int> dictionary = new Dictionary<int, int>();

List<Pair<int, int>> list = new List<Pair<int, int>>();

list.Add(new Pair<int,int>(12, 10));

list.Add(new Pair<int,int>(11, 12));

list.Add(new Pair<int,int>(10, 13));

list.ForEach(l => Console.WriteLine(l));

Console.WriteLine();

 

dictionary = Pair<int, int>.ListToDictionary(list);

dictionary.Keys.ToList().ForEach(k =>

{

Console.WriteLine(k + “: “ + dictionary[k]);

});

Console.WriteLine();

 

list = Pair<int, int>.DictionaryToList(dictionary);

list.ForEach(l => Console.WriteLine(l));

Console.WriteLine();

 

list = new List<Pair<int, int>>();

list.Add(new Pair<int,int>(12, 10));

list.Add(new Pair<int,int>(12, 12));

list.Add(new Pair<int,int>(12, 13));

list.ForEach(l => Console.WriteLine(l));

Console.WriteLine();

 

var dictionary2 = Pair<int,int>.ListToDictionaryDimension(list);

dictionary2.Keys.ToList().ForEach(k =>

{

string tmp = string.Empty;

(dictionary2[k] as List<int>).ForEach(l => tmp += l.ToString() + ” “);

Console.WriteLine(k + “: “ + tmp);

});

Console.WriteLine();

Console.Read();

 

When someone has idea how to improve it let me know.

 

Happy Coding :)

Follow

Get every new post delivered to your Inbox.