#PowerShell, #PowerWiseScripting, #ProjectWise, PWPS_DAB

HowTo: Filter Documents on Dates

In this post, we will be creating a function (Get-PWDocumentsBetween) to filter an array of ProjectWise Documents based on the FileUpdatedDate and / or the DocumentUpdatedDate. I realise the Get-PWDocumentsBySearchWithReturnColumns  cmdlet allows you to filter the documents returned on the  FileUpdatedDate.  However, it does not offer a method to filter on the DocumentUpdatedDate.  Hence the reason for this post. NOTE: We may add this functionality to the cmdlet at a later date.   We will not be utilizing any cmldets specifically provided for use with ProjectWise. I would recommend that you become familiar with the Get-PWDocumentsBySearchWithReturnColumns to understand how it works and uses the FileUpdatedBefore and FileUpdatedAfter parameters.

FUNCTION Definition

The following is the function wrapper which will contain the remainder of the code.
FUNCTION Get-PWDocumentsBetween {
    <#
        .Synopsis
        Filters the provided ProjectWise Document objects using the start and end dates provided.
        .DESCRIPTION
        Only those ProjectWise Documents which which meet the date criteria (have file updated dates or documents updated dates which fall between the start and end dates) will be returned.
        If a start and end date is not provided, all documents will be returned.
        .INPUTS
        ProjectWiseDocumentsToCheck - one or more ProjectWise Document objects can be passed via the pipeline.
        .OUTPUTS
        Array of ProjectWiseDocument objects.        
        .EXAMPLE
        $pwDocs = Get-PWDocumentsBySearch -FolderID 43899 -GetAttributes
        $Splat_FilterDocs = @{
            ProjectWiseDocumentsToCheck = $pwDocs
            StartDate = "8/26/2019 01:00:00"
            EndDate = "03/04/2020 13:00:00"
            DocumentUpdateDate = $true
            FileUpdateDate = $true
        }
        Get-PWDocsBetween @Splat_FilterDocs -Verbose |
        Select-Object -Property Name, FileUpdateDate, DocumentUpdateDate
    #>

    #Requires -Version 5.0
    
    [CmdletBinding()]
    param (...) # end param...

    BEGIN {...} # end BEGIN...

    PROCESS {...} # end PROCESS...

    END{...} # end END...
} # end FUNCTION Get-PWDocumentsBetween...
Export-ModuleMember -Function Get-PWDocumentsBetween

Parameters

First thing we need to do is create our parameter and value pairs. The help messages will explain the purpose for each parameter.
param ( 
    # One or more document object to filter on.
    [ValidateNotNullOrEmpty()] 
    [Parameter(
        HelpMessage = "One or more document object to filter on.",
        Position = 0,
        Mandatory = $true )]
    [PSObject[]] $ProjectWiseDocumentsToCheck,

    # Begin date to use to filter documents.
    [ValidateNotNullOrEmpty()]
    [Parameter(
        HelpMessage = "Begin date to use to filter documents.",
        Position = 1,
        Mandatory = $false )]
    [string] $StartDate = [datetime]::MinValue,

    # End date to use to filter documents.
    [ValidateNotNullOrEmpty()]
    [Parameter(
        HelpMessage = "End date to use to filter documents.",
        Position = 2,
        Mandatory = $false )]
    [string] $EndDate = ([datetime]::UtcNow).AddDays(1),

    # When included, file updated date will be used to filter documents.
    [Parameter(
        HelpMessage = "When included, document updated date will be used to filter documents.",
        Mandatory = $false )]
    [String] $FileUpdateDate,

    # When included, document updated date will be used to filter documents.
    [Parameter(
        HelpMessage = "When included, document updated date will be used to filter documents.",
        Mandatory = $false )]
    [String] $DocumentUpdateDate

) # end param...

Begin

I want to take a second and point out a couple of conventions that I use in my scripts. First, you may notice that I put a comment at the end of many of the blocks of code. Doing this makes it easier for me to determine where a block of code starts and ends. Comes in handy when troubleshooting a script.  I also add text ([BEGIN], [PROCESS], [END]) in the output messages (Write-Verbose, Write-Warning, Write-Error) corresponding to the section of the script I am in. Again, this makes it obvious where something occurs within the script. In this section, I am setting the values for both the start and end dates. If they are not supplied, the start date will default to ’01/01/0001′ and the end date will default to todays date plus one.
BEGIN {  
    # Gets todays date and adds one day. Ensures the entire day is included when used.
    $Today = ([datetime]::UtcNow).AddDays(1)
    $MinValue = [datetime]::MinValue

    # Sets the start and end times if they are not included.
    if($FileUpdateDate){
        $FileUpdateStart = $StartDate
        $FileUpdateEnd = $EndDate
    } else {
        $FileUpdateStart =  $MinValue.ToShortDateString()
        $FileUPdateEnd = $Today.ToShortDateString()
    }
    if($DocumentUpdateDate){
        $DocumentUpdateStart = $StartDate
        $DocumentUpdateEnd = $EndDate
    } else {
        $DocumentUpdateStart =  $MinValue.ToShortDateString()
        $DocumentUpdateEnd = $Today.ToShortDateString()
    }
    Write-Verbose -Message "[BEGIN] FileUpdate start: $FileUpdateStart; end: $FileUpdateEnd"
    Write-Verbose -Message "[BEGIN] DocumentUpdate start: $DocumentUpdateStart; end: $DocumentUpdateEnd"

} # end BEGIN...

PROCESS

Now, we will proceed to the PROCESS code block. In this section, the $Return variable will be populated with only those ProjectWise Document objects which meet the date criteria. We are simply using a Where-Object to filter the provided ProjectWise Document objects on the FileUpdateDate and the DocumentUpdateDate.
PROCESS {
    $Return = $ProjectWiseDocumentsToCheck | 
    Where-Object { 
        $_.FileUpdateDate -ge $FileUpdateStart -and 
        $_.FileUpdateDate -lt $FileUpdateEnd -and 
        $_.DocumentUpdateDate -ge $DocumentUpdateStart -and
        $_.DocumentUpdateDate -lt $DocumentUpdateEnd
    }

} # end PROCESS...

END

Lastly, we will proceed to the END block of code. We will return the filtered ProjectWise Document objects is any meet the date criteria. Otherwise, we return a false.
END {
    if( -not ([string]::IsNullOrEmpty($Return))) { 
        Write-Output -InputObject $Return
    } else {
        Write-Warning -Message "No documents meet the provide date criteria."
        Write-Output $false
    }
} # end END...

The following is a link to the full PowerShell script. HowTo-GetPWDocumentsBetween Experiment with it and have fun. Hopefully, you find this useful. Please let me know if you have any questions or comments.  If you like this post, please click the Like button at the bottom of the page.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.