SharePoint Automation Gary Lapointe – Founding Partner, Aptillon, Inc.

26Jun/1110

Getting (and taking ownership of) Checked Out Files using Windows PowerShell

Often when I’m working on a project I need to generate a list of all checked out files and provide that to my client just prior to release to production. Sometimes the client will manually inspect each of them and act as they see fit and other times they’ll ask me to just batch publish all of them (for which I use my Publish-SPListItems cmdlet). So, how do I generate the report for the client? It’s actually pretty easy using PowerShell and a couple of quick loops. Here’s an example that loops through every Site Collection in the Farm and generates a nice report:

function Get-CheckedOutFiles() {
    foreach ($web in (Get-SPSite -Limit All | Get-SPWeb -Limit All)) {
        Write-Host "Processing Web: $($web.Url)..."
        foreach ($list in ($web.Lists | ? {$_ -is [Microsoft.SharePoint.SPDocumentLibrary]})) {
            Write-Host "`tProcessing List: $($list.RootFolder.ServerRelativeUrl)..."
            foreach ($item in $list.CheckedOutFiles) {
                if (!$item.Url.EndsWith(".aspx")) { continue }
                $hash = @{
                    "URL"=$web.Site.MakeFullUrl("$($web.ServerRelativeUrl.TrimEnd('/'))/$($item.Url)");
                    "CheckedOutBy"=$item.CheckedOutBy;
                    "CheckedOutByEmail"=$item.CheckedOutByEmail
                }
                New-Object PSObject -Property $hash
            }
            foreach ($item in $list.Items) {
                if ($item.File.CheckOutStatus -ne "None") {
                    if (($list.CheckedOutFiles | where {$_.ListItemId -eq $item.ID}) -ne $null) { continue }
                    $hash = @{
                        "URL"=$web.Site.MakeFullUrl("$($web.ServerRelativeUrl.TrimEnd('/'))/$($item.Url)");
                        "CheckedOutBy"=$item.File.CheckedOutByUser;
                        "CheckedOutByEmail"=$item.File.CheckedOutByUser.Email
                    }
                    New-Object PSObject -Property $hash
                }
            }
        }
        $web.Dispose()
    }
}
Get-CheckedOutFiles | Out-GridView

Running the above will generate a fairly nice report with URLs and usernames and whatnot; you could also use the Export-Csv cmdlet to dump the results to a CSV file that you can then hand off to your end-users. One cool thing to point out about this is that it will also show you files that you normally can’t see – that is files that have been created by other users but have never had a check in. This is actually pretty cool and I stumbled upon this when trying to fine tune my Publish-SPListItems cmdlet. You see, if the file has never been checked in then iterating through the SPListItemCollection object will not reveal the item (or file I should say); this meant that my cmdlet, as it was previously written, was missing a bunch of files. So to work around this all I had to do was add an additional loop to iterate over the collection returned by the SPDocumentLibrary’s CheckedOutFiles property. For each SPCheckedOutFile object in that collection I then call TakeOverCheckOut() to grab the checked out file so that I can then publish.

I use this enough that I decided to turn it into a cmdlet that is now part of my custom extensions. Like the above script, I return back a custom object that contains the full URLs and other  useful information (such as the List, Site, and Site Collection identifiers). I also exposed a TakeOverCheckOut() and Delete() method which simply calls Microsoft’s implementation of those methods.

I called this cmdlet Get-SPCheckedOutFiles (note that I’d previously released this cmdlet under the name Get-SPFilesCheckedOut but have since reworked and renamed that original implementation).

Here’s the full help for the cmdlet:

PS C:\Users\spadmin> help Get-SPCheckedOutFiles -full

NAME
Get-SPCheckedOutFiles

SYNOPSIS
Retrieves check out details for a given List, Web, or Site.

SYNTAX
Get-SPCheckedOutFiles [-Site] <SPSitePipeBind> [-AssignmentCollection <SPAssignmentCollection>] [<CommonParameters>]

Get-SPCheckedOutFiles [-Web] <SPWebPipeBind> [-ExcludeChildWebs <SwitchParameter>] [-AssignmentCollection <SPAssignmentCollection>] [<CommonParameters>]

Get-SPCheckedOutFiles [[-Web] <SPWebPipeBind>] [-List] <SPListPipeBind> [-AssignmentCollection <SPAssignmentCollection>] [<CommonParameters>]


DESCRIPTION
Retrieves check out details for a given List, Web, or Site.

Copyright 2010 Falchion Consulting, LLC
> For more information on this cmdlet and others:
>
http://blog.falchionconsulting.com/
> Use of this cmdlet is at your own risk.
> Gary Lapointe assumes no liability.

PARAMETERS
-Site <SPSitePipeBind>
Specifies the URL or GUID of the Site to inspect.

The type must be a valid GUID, in the form 12345678-90ab-cdef-1234-567890bcdefgh; a valid URL, in the form
http://server_name; or an instance of a valid SPSite object.

Required? true
Position? 1
Default value
Accept pipeline input? true (ByValue, ByPropertyName)
Accept wildcard characters? false

-Web <SPWebPipeBind>
Specifies the URL or GUID of the Web to inspect.

The type must be a valid GUID, in the form 12345678-90ab-cdef-1234-567890bcdefgh; a valid URL, in the form
http://server_name; or an instance of a valid SPWeb object.

Required? true
Position? 1
Default value
Accept pipeline input? true (ByValue, ByPropertyName)
Accept wildcard characters? false

-List <SPListPipeBind>
The list whose checked out files are to be returned.

The value must be a valid URL in the form
http://server_name/lists/listname or /lists/listname. If a server relative URL is provided then the Web parameter must be provided.

Required? true
Position? 1
Default value
Accept pipeline input? true (ByValue, ByPropertyName)
Accept wildcard characters? false

-ExcludeChildWebs [<SwitchParameter>]
Excludes all child sites and only considers the specified site.

Required? false
Position? named
Default value
Accept pipeline input? false
Accept wildcard characters? false

-AssignmentCollection [<SPAssignmentCollection>]
Manages objects for the purpose of proper disposal. Use of objects, such as SPWeb or SPSite, can use large amounts of memory and use of these objects in Windows PowerShell scripts requires proper memory management. Using the SPAssignment object, you can assign objects to a variable and dispose of the objects after they are needed to free up memory. When SPWeb, SPSite, or SPSiteAdministration objects are used, the objects are automatically disposed of if an assignment collection or the Global parameter is not used.

When the Global parameter is used, all objects are contained in the global store. If objects are not immediately used, or disposed of by using the Stop-SPAssignment command, an out-of-memory scenario can occur.

Required? false
Position? named
Default value
Accept pipeline input? true (ByValue)
Accept wildcard characters? false

<CommonParameters>
This cmdlet supports the common parameters: Verbose, Debug, ErrorAction, ErrorVariable, WarningAction, WarningVariable, OutBuffer and OutVariable. For more information, type, "get-help about_commonparameters".

INPUTS

OUTPUTS

NOTES

For more information, type "Get-Help Get-SPCheckedOutFiles -detailed". For technical information, type "Get-Help Get-SPCheckedOutFiles -full".

------------------EXAMPLE------------------

PS C:\> Get-SPCheckedOutFiles -Site "
http://server_name/"


This example outputs a list of files that are checked out for the given Site Collection


RELATED LINKS
Get-SPFile

 

In the following example I’m retrieving pages from the root Pages library that are checked out:

image

In this example I am running the cmdlet as the aptillon\spadmin user and I’m now able to see the checkout by the user aptillon\glapointe. I ran the cmdlet twice so you could see the default tabular view as well as the more detailed view. Again, you could easily use the Export-Csv cmdlet to dump this information to a file that you can provide your end-users.

I hope you find this cmdlet useful – it personally has proven invaluable to me, particularly when working on anonymous access internet sites as end-users are notorious about creating pages and not getting them checked in.

P.S. With this release the Publish-SPListItems cmdlet has been updated to now consider files that don’t have any existing check-ins.

Comments (10) Trackbacks (9)
  1. Hi Gary,

    Thanks very much for this script. it is very useful in my case. I am modifying you script to work for SP 2007 and it works very well.

    i had even further modified it to get check out files based on user.

    The last thing i want it to get the out put result in a table format and i am having difficulties to get its out put in table format. its get the results in rows instead of Column.

    Do you know any work around for that.

  2. Hi Gary, great post. Helped me out a lot

    For those that are interested in doing this for MOSS 2007 this is what I used:

    [System.Reflection.Assembly]::Load(“Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c”)

    $siteURL=”http://portal/site”
    $site=New-Object Microsoft.SharePoint.SPSite($siteURL)

    function Get-CheckedOutFiles() {
    foreach ($web in $site.AllWebs) {
    Write-Host “Processing Web: $($web.Url)…”
    foreach ($list in ($web.Lists | ? {$_ -is [Microsoft.SharePoint.SPDocumentLibrary]})) {
    Write-Host “`tProcessing List: $($list.RootFolder.ServerRelativeUrl)…”
    foreach ($item in $list.CheckedOutFiles) {
    if (!$item.Url.EndsWith(“.aspx”)) { continue }
    $hash = @{
    “URL”=$web.Site.MakeFullUrl(“$($web.ServerRelativeUrl.TrimEnd(‘/’))/$($item.Url)”);
    “CheckedOutBy”=$item.CheckedOutBy;
    “CheckedOutByEmail”=$item.CheckedOutByEmail
    }
    New-Object PSObject -Property $hash
    }
    foreach ($item in $list.Items) {
    if ($item.File.CheckOutStatus -ne “None”) {
    if (($list.CheckedOutFiles | where {$_.ListItemId -eq $item.ID}) -ne $null) { continue }
    $hash = @{
    “URL”=$web.Site.MakeFullUrl(“$($web.ServerRelativeUrl.TrimEnd(‘/’))/$($item.Url)”);
    “CheckedOutBy”=$item.File.CheckedOutBy;
    “CheckedOutByEmail”=$item.File.CheckedOutBy.Email
    }
    New-Object PSObject -Property $hash
    }
    }
    }
    $web.Dispose()
    }
    }
    Get-CheckedOutFiles | Out-GridView | export-csv c:\temp\checkedout.csv

    Also Gary I noticed this script only lists Checked Out items that have never been checked-in before. How do I list All checked-out items regardless if they have never been checked in before?

    Thanks

    v/r
    JShidell

    • Hi JShidell

      I´d like to know how do you use your code in MOSS 2007 as it doesn´t has a specific Sharepoint Power Shell as 2010 does. I´ve copied your code but I don´t know how to run it in MOSS 2007.

      Can you help me?
      Tks a lot!

      Rafael Machado

  3. Hi Gary,

    Is there a way you can show me how you did this?

    “One cool thing to point out about this is that it will also show you files that you normally can’t see – that is files that have been created by other users but have never had a check in. This is actually pretty cool and I stumbled upon this when trying to fine tune my Publish-SPListItems cmdlet. You see, if the file has never been checked in then iterating through the SPListItemCollection object will not reveal the item (or file I should say); this meant that my cmdlet, as it was previously written, was missing a bunch of files. So to work around this all I had to do was add an additional loop to iterate over the collection returned by the SPDocumentLibrary’s CheckedOutFiles property. For each SPCheckedOutFile object in that collection I then call TakeOverCheckOut() to grab the checked out file so that I can then publish.”

    Thanks

    vr
    JShidell

  4. Hi Gary,
    I am not clear on why you skip over the checked-out files that do not have ‘.aspx’ file extensions in the first loop that goes through the document library’s checked-out files:

    if (!$item.Url.EndsWith(“.aspx”)) { continue }

    Am I missing something? Please let me know. Thank you.

    • You can remove that line. When I created this it was specifically for a case where I was only looking for .aspx files and I guess I forgot to remove that line for this more generic example.


Leave a comment

CAPTCHA Image

*