Updated PowerShell script to insert copyright notice/banner/header in all source code files

In a recent post I described how one could insert a copyright banner in all source code files located on a given path. You can read all the details about it here: Inserting copyright notice/banner/header in all source code files with PowerShell script

During the past month or so I updated that PowerShell script to give it even more power. In the Notes section of that post I mentioned this point:


  • Beware that if you run the script twice it'll add the copyright notice twice in each file

With this updated version (see the highlighted parts) I’ve overcome such limitation.

I’m now also using the built-in Powershell Filter keyword to filter the files, that is, processing only .cs files (C# code files) excluding some other files that have the .cs extension but that have a given naming pattern. I exclude those files because it doesn’t make sense to add copyright to them and because in some cases it would break the build.

Here’s the updated PowerShell script with comments to help you understand what’s going on in each line:

param($target = "C:\MyProject\trunk", $companyname = "Leniel’s Software House")

#[System.Globalization.CultureInfo] $ci = [System.Globalization.CultureInfo]::GetCultureInfo("pt-BR")

[System.Globalization.CultureInfo] $ci = [System.Globalization.CultureInfo]::GetCurrentCulture

# Full date pattern with a given CultureInfo
# Look here for available String date patterns: http://www.csharp-examples.net/string-format-datetime/
$date = (Get-Date).ToString("F", $ci);

# Header template
$header = "//-----------------------------------------------------------------------

// <copyright file=""{0}"" company=""{1}"">

// Copyright (c) {1}. All rights reserved.

// <author>Leniel Macaferi</author>

// <date>{2}</date>

// </copyright>

//-----------------------------------------------------------------------`r`n"

function Write-Header ($file)
{
    # Get the file content as as Array object that contains the file lines
    $content = Get-Content $file
    
    # Getting the content as a String
    $contentAsString =  $content | Out-String
    
    <# If content starts with // then the file has a copyright notice already
       Let's Skip the first 14 lines of the copyright notice template... #>
    if($contentAsString.StartsWith("//"))
    {
       $content = $content | Select-Object -skip 14
    }

    # Splitting the file path and getting the leaf/last part, that is, the file name
    $filename = Split-Path -Leaf $file

    # $fileheader is assigned the value of $header with dynamic values passed as parameters after -f
    $fileheader = $header -f $filename, $companyname, $date

    # Writing the header to the file
    Set-Content $file $fileheader -encoding UTF8

    # Append the content to the file
    Add-Content $file $content
}

#Filter files getting only .cs ones and exclude specific file extensions
Get-ChildItem $target -Filter *.cs -Exclude *.Designer.cs,T4MVC.cs,*.generated.cs,*.ModelUnbinder.cs -Recurse | % `
{
    <# For each file on the $target directory that matches the filter,
       let's call the Write-Header function defined above passing the file as parameter #>
    Write-Header $_.PSPath.Split(":", 3)[2]
}
Hope you make even better use of such a pearl that comes in handy from time to time.