Scripts/WorkAreaUpdates/CDOT_UpdatePWProjectCatalogDocs_v01.ps1
##################################################################################################################################################################################################################### ##############################| |#################################################################################################################################################################################### ##############################| |# ############## ########| |# Name : CDOT_UpdatePWAssetCatalogDocs_v01 ########### #####| |# Type : Script ######### ####### ####| |# Purpose : Update ProjectWise Documents with Asset Info from a SQL Query ######## ############ ####| |# Author : Adrian J. Crowfoot ####### ##### ##### ####| |# Creation Date : 10/23/2019 ############## ##### #####| |# Modified By : Adrian J. Crowfoot ############# ### ######| |# Modified Date : 12/04/2019 ########## #######| |# Script Version : 1.2 ######## ##########| |# PowerShell Version : 5.1.16299.1146 ######## ##############| |# ProjectWise Version : 10.00.03.167 ######### #########| |# PWPS Module Version : 10.0.2.1 ######## ###### ########| |# PWPS_DAB Module Version : 1.16.3.0 ####### ######### #######| |# PWPS_CDOT Module Version : 1.0.1.0 ####### ########## #######| |# ###### ######### ########| |# Requirements: ###### #### ########| |# - Ability to log into a ProjectWise Datasource with Administrative privileges. ###### ##########| |# - Data Table using Get-PWRichProjectReport and other parameters ######### #############| |# - Logged into a ProjectWise datasource. ##############################| |# - ##############################| |# ##################################################################################################################################################################################################################### ## ## Description/Notes: ## - ## - [AJC 20191122] Reworked script to require an active PW Login and to simplify logging. ## - [AJC 20191203] Finished BEGIN block ## - [AJC 20191204] Finished PROCESS Block to create and/or update Project Catalog documents ## - [AJC 20200127] Reworked to accept two parameter sets: DataTable ($dtPWRichProjects, $PWProjectNumberProperty) or ArrayList ($ProjectCodes) ## ##################################################################################################################################################################################################################### ## ## This script is provided for example purposes only. Bentley makes no warranty as to the effectiveness of this script in a specific situation or for a specific user. ## Use of this script or a similar script in a production environment is entirely at the risk of the user. Bentley suggests extensive testing before deployment. ## ##################################################################################################################################################################################################################### #Requires -Version 5.0 #Requires -Modules @{ModuleName="PWPS_DAB";ModuleVersion='1.16.0.0'} #Requires -Modules @{ModuleName="PWPS_CDOT";ModuleVersion='1.0.1.0'} ##Requires -RunAsAdministrator <#PSScriptInfo .VERSION 1.3 .GUID 10ec7184-50aa-4e4f-87b4-9d571a2782fd .AUTHOR adrian.crowfoot@state.co.us .COMPANYNAME Colorado DOT .TAGS ProjectWise .EXTERNALMODULEDEPENDENCIES PWPS_DAB PWPS_CDOT .REQUIREDSCRIPTS CDOT_GetPWRichProjectDataTable_v01 CDOT_UpdatePWProjects_v02 CDOT_UpdatePWProjectCatalogDocs_v01 .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES #> <# .DESCRIPTION Update ProjectWise Documents with Asset Info from a SQL Query #> [CmdletBinding()] param( ############################################################################################# # Parameters to select pertinent data from a Data Table (DataTable Parameter Set) ############################################################################################# [Parameter( HelpMessage = 'Datatable listing input project paths and project numbers', Mandatory =$true, ParameterSetName ='DataTable')] [System.Data.DataTable] $dtPWRichProjects, # Input Rich Project Datatable [Parameter( HelpMessage = 'Work Area Properties Type', Mandatory =$true, ParameterSetName ='DataTable')] [String]$PWProjectNumberProperty, ############################################################################################# # Parameters to select pertinent data from a list of projects (ArrayList Parameter Set) ############################################################################################# [Parameter( HelpMessage = 'Array listing input project numbers', Mandatory =$true, ParameterSetName ='ArrayList')] [String[]] $ProjectCodes, # Input Rich Project Datatable ########################################################################################### # Parameters for Comparing Asset Data in CDOTDATA vs. ProjectWise Environment ########################################################################################### [Parameter( HelpMessage = "Name of Environment that contains Asset Information", Mandatory =$true)] [string] $PWEnvironmentName, # = 'CDOT Data - Project Catalog', [Parameter( HelpMessage = "Project Number Attribue Name", Mandatory =$true)] [string] $PWProjectNumberAttribute, # = 'projCode', [Parameter( HelpMessage = "Name of attribute to compare", Mandatory =$true)] [string] $PWProjectTimeStampUpdateAttribute, # = 'projChangeDate', [Parameter( Mandatory = $false )] [string] $PWFolderRootPath = "04 Admin Configuration\Project Catalog", [Parameter( Mandatory = $false )] [string] $PWAssetDocumentPrefix = "PRJ", ########################################################################################### # Define SQL Parameters ########################################################################################### # SQL Server Information (uses Windows Authentication) [Parameter( HelpMessage = "SQL Server that houses input database and table", Mandatory = $true )] [string] $SQLServer, # = 'IntProdListener', [Parameter( HelpMessage = "SQL Server Instance that houses input database and table", Mandatory = $true )] [string] $SQLInstanceName, # = 'Default', [Parameter( HelpMessage = "SQL database that contains input table(s)", Mandatory = $true )] [string] $SQLDatabase, # = 'CDOTDATA', # Edit the SQL Query file to get the correct columns from CDOTDATA [Parameter( HelpMessage = "SQL Query file that returns the input datatable", Mandatory = $true )] [string] $SqlQueryFile, # = "$(Get-CDOTModuleLocation)\CDOTDATA_ProjectInfo.sql", ########################################################################################### # Script and Log File Information ########################################################################################### [ValidateNotNullOrEmpty()] [ValidateScript( { Test-Path -Path $_ -PathType Container })] [Parameter( HelpMessage = "Location of script file and log folder.", Mandatory = $true, Position = 3 )] [string] $Path, [ValidateNotNullOrEmpty()] [Parameter( HelpMessage = "Log file to be generated for each run of the script.", Mandatory = $true, Position = 7 )] [string] $LogFilePathName ) BEGIN { $CmdletName = $MyInvocation.MyCommand.Name Write-PWPSLog -Message " - " -Path $LogFilePathName -Level Info -Cmdlet $CmdletName Write-PWPSLog -Message "[BEGIN] Entering Update ProjCatalog Documents script." -Path $LogFilePathName -Level Info -Cmdlet $CmdletName $ScriptStartTime = Get-Date Write-PWPSLog -Message "[BEGIN] Start time: $ScriptStartTime" -Path $LogFilePathName -Level Info -Cmdlet $CmdletName #region Check Datatable for Unique Values and rows try { if ($dtPWRichProjects) { # Process datatable $projectList = $dtPWRichProjects.Rows.$PWProjectNumberProperty | Sort-Object -Unique | Where-Object $PWProjectNumberProperty -ne 0 | Where-Object $PWProjectNumberProperty -ne '' if($projectList.Count -eq 0) { throw "No Projects to Process" } $SqlWhereCondition = "WHERE $PWProjectNumberAttribute IN (" + "'$($projectList -join "','")'" + ")" Write-PWPSLog -Message "[BEGIN] $($projectList.Count) distinct $PWProjectNumberAttribute values in Data table" -Path $LogFilePathName -Level Info -Cmdlet $CmdletName } else { # Process array $projectList = $ProjectCodes | Sort-Object -Unique if($projectList.Count -eq 0) { throw "No Projects to Process" } $SqlWhereCondition = "WHERE $PWProjectNumberAttribute IN (" + "'$($projectList -join "','")'" + ")" Write-PWPSLog -Message "[BEGIN] $($projectList.Count) distinct Project Codes in Array" -Path $LogFilePathName -Level Info -Cmdlet $CmdletName } # SQL Connection string to load from correct instance of CDOTDATA $SQLConnectionString = "Server=$SQLServer; Database=$SQLDatabase; Integrated Security=true;Connect Timeout=30" # A. Build the SQL Query from the SQL Query File and the SQL Where Condition $SqlQuery = $(Get-Content $SqlQueryFile -Raw) + $SqlWhereCondition # B. Create Data Table using Select-SQLDataTable function in PWPS_CDOT $dtCDOTDATA = Select-CDOTSQLDataTable -SQLConnectionString $SQLConnectionString -SqlQuery $SqlQuery -TableName 'Properties' if($dtCDOTDATA.Rows.Count -eq 0) { throw "No Rows in Data table" } Write-PWPSLog -Message "[BEGIN] $($dtCDOTDATA.Rows.Count) Distinct Projects in Data table" -Path $LogFilePathName -Level Info -Cmdlet $CmdletName } catch { $Line = $($Error[0].InvocationInfo.ScriptLineNumber) $ErrorMessage = $($Error[0].Exception.Message) Write-PWPSLog -Message "[BEGIN] Occurred on line: $Line. $ErrorMessage" -Path $LogFilePathName -Level Warn -Cmdlet $CmdletName Write-PWPSLog -Message "[BEGIN] Exiting Script." -Path $LogFilePathName -Level Warn -Cmdlet $CmdletName break } # End Try Catch #endregion Check Datatable for Unique Values and rows #region Check ProjectWise Environment and Column Name try { if ($PWEnvironmentName -notin $(Get-PWEnvironments).Name) { throw "$PWEnvironmentName NOT found. Please add it to $PWDatasource." } Write-PWPSLog -Message "[BEGIN] $PWEnvironmentName found in ProjectWise datasource" -Path $LogFilePathName -Level Info -Cmdlet $CmdletName # Find $PWProjectNumberAttribute in list of $PWEnvironmentName columns. If not, exit script. $PWEnvironmentAttributeNames = $(Get-PWEnvironmentColumns -EnvironmentName $PWEnvironmentName).Name if($PWProjectNumberAttribute -notin $($PWEnvironmentAttributeNames)) { throw "$PWProjectNumberAttribute NOT found in $PWEnvironmentName. Please add it to $PWEnvironmentName." } Write-PWPSLog -Message "[BEGIN] $PWProjectNumberAttribute found in $PWEnvironmentName." -Path $LogFilePathName -Level Info -Cmdlet $CmdletName } catch { $Line = $($Error[0].InvocationInfo.ScriptLineNumber) $ErrorMessage = $($Error[0].Exception.Message) Write-PWPSLog -Message "[BEGIN] Occurred on line: $Line. $ErrorMessage" -Path $LogFilePathName -Level Warn -Cmdlet $CmdletName Write-PWPSLog -Message "[BEGIN] Exiting Script." -Path $LogFilePathName -Level Warn -Cmdlet $CmdletName break } # End Try Catch #endregion Check ProjectWise Environment and Column Name } # end BEGIN PROCESS { # ALL INFORMATION IS LOADED IN $dtCDOTDATA but does not include rogue project numbers # $projectList contains all unique project codes (including bogus ones) - only use real ones # Process each Project Code in Project Array to find which ones need SAP Update foreach ($row in $dtCDOTDATA.Rows) { $projectCode = $row.$PWProjectNumberAttribute # Create new document if not exists - store document in $docToUpdate if ( -not ($docToUpdate = Get-PWDocumentsBySearch -Environment $PWEnvironmentName -Attributes @{$PWProjectNumberAttribute = $projectCode } -FolderPath $PWFolderRootPath -GetAttributes)) { $Splat_NewDoc = @{ InputFolders = (Get-PWFolders -FolderPath $PWFolderRootPath -JustOne) DocumentName = "$PWAssetDocumentPrefix$projectCode" Description = "$PWAssetDocumentPrefix$projectCode" Count = 1 DoNotAddSuffix = $true } $docToUpdate = New-PWDocumentAbstract @Splat_NewDoc -Verbose } if ($docToUpdate) { # Get update date in CDOTDATA $databaseAttributeValue = $row.$PWProjectTimeStampUpdateAttribute $PWAttributeValue = $docToUpdate.CustomAttributes.$PWProjectTimeStampUpdateAttribute if ($databaseAttributeValue -ne $PWAttributeValue) { # Reset HashTable for PW Document Attributes $PWDoc_Attributes = @{} # Extract one Row from Datatable $drProject = $dtCDOTDATA.Select("$PWProjectNumberAttribute = $projectCode") foreach ($attribute in $PWEnvironmentAttributeNames){ if ($drProject.$attribute) { $PWDoc_Attributes.$attribute = $drProject.$attribute } } if( -not (Update-PWDocumentAttributes -Attributes $PWDoc_Attributes -InputDocuments $docToUpdate -ReturnBoolean)){ Write-PWPSLog -Message "[PROCESS] Failed to update attributes for $($docToUpdate.Name)." -Path $LogFilePathName -Level Warn -Cmdlet $CmdletName } else { Write-PWPSLog -Message "[PROCESS] $($docToUpdate.Name) was changed." -Path $LogFilePathName -Level Info -Cmdlet $CmdletName } } else { # DOCUMENT DOES NOT NEED TO BE UPDATED Write-PWPSLog -Message "[PROCESS] No changes for $($docToUpdate.Name)." -Path $LogFilePathName -Level Info -Cmdlet $CmdletName } } # end if $docToUpdate exists else { # Document was not found and not created properly Write-PWPSLog -Message "[PROCESS] Failed to find or create document for $projectCode." -Path $LogFilePathName -Level Warn -Cmdlet $CmdletName } } # end for $row } # end PROCESS END { $ScriptEndTime = Get-Date Write-PWPSLog -Message "[END] It took $([Math]::Round($ScriptEndTime.Subtract($ScriptStartTime).TotalMinutes, 2)) minutes to complete the process." -Path $LogFilePathName -Level Info -Cmdlet $CmdletName Write-PWPSLog -Message "[END] Leaving script." -Path $LogFilePathName -Level Info -Cmdlet $CmdletName Write-PWPSLog -Message " - " -Path $LogFilePathName -Level Info -Cmdlet $CmdletName } # end END |