UpgradeWizard/UpgradeWizard.ps1
function UpgradeWizard { param( [Parameter(Mandatory=$true)] [ValidateSet('True','False')] [string]$SkipQuestions ) [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') | Out-Null $total = 10; $counter1 = 1; [string]$test = ''; [string]$inputStr =''; cls; Write-Progress -activity "Upgrade Wizard" -status "Step $counter1 of $total (CUSTOMER)" -PercentComplete (($counter1 / $total) * 100); [string]$CustomerDB = UW-Get-TFSFolders -Desc 'Specify Customer Database (Source modified)' ; $counter1 += 1; $intAnswer = 99; try { $AppVersion = "$CustomerDB/COD1.TXT" $FileContent = Invoke-TFSAPIUW -Url ('_apis/tfvc/items/{0}' -f $AppVersion) -GetContents -NoRaw 'false' $FileContent = $FileContent|Select-String -Pattern "PROCEDURE ApplicationBuild" -Context 1,2 $FileContent2 = $FileContent.Context.PostContext $FileContent3 = $FileContent2|Select-String -Pattern "EXIT" $FileContent4 = $FileContent3.Line $AppVersion = $FileContent4.Remove(0, $FileContent4.IndexOf('(''')+2) $AppVersion = $AppVersion.Remove($AppVersion.IndexOf(''')')) $AllBranches = Get-TFSBranches [string]$BaseSourceFound = $AllBranches -like "*$AppVersion*" $VersionMsg = $BaseSourceFound.Remove(0, 22) $popup = new-object -comobject wscript.shell $intAnswer = $popup.popup("The script discovered that the Customer Database Version is $VersionMsg`nDo you want to use this version as a Base Source Version?", 0,"Customer Version Detection",4) } catch {} if ($intAnswer -ne 6){ Write-Progress -activity "Upgrade Wizard" -status "Step $counter1 of $total (Current BASE)" -PercentComplete (($counter1 / $total) * 100); [string]$BaseSource = UW-Get-TFSFolders -LevelPath '$/NAV - Base Versions' -Desc 'Specify CURRENT CUSTOMER BASE version (Source base)' ; } else { [string]$BaseSource = $BaseSourceFound } $counter1 += 1; Write-Progress -activity "Upgrade Wizard" -status "Step $counter1 of $total (TARGET BASE)" -PercentComplete (($counter1 / $total) * 100); [string]$BaseTarget = UW-Get-TFSFolders -LevelPath '$/NAV - Base Versions' -Desc 'Specify TARGET CUSTOMER BASE version (Target base)' ; $counter1 += 1; Write-Progress -activity "Upgrade Wizard" -status "Step $counter1 of $total (WORK FOLDER)" -PercentComplete (($counter1 / $total) * 100); $WorkFolder = [Microsoft.VisualBasic.Interaction]::InputBox("Enter work folder path", "Work folder", "") if ($WorkFolder -eq '') { Write-Host 'Canceled by the user' breakl } $counter1 += 1; Write-Progress -activity "Upgrade Wizard" -status "Step $counter1 of $total (Creating folder structure)" -PercentComplete (($counter1 / $total) * 100); $counter1 += 1; Try { $BaseSourceF = UW-RemoveCharFromString -text $BaseSource; $BaseTargetF = UW-RemoveCharFromString -text $BaseTarget; $CustomerDBF = UW-RemoveCharFromString -text $CustomerDB; } Catch { Write-Host Write-Host Write-Host Write-Host Write-Host Write-Host Write-Host Write-Host Write-Host 'The TFS folder structure is sooo wrong - there is only one level of folder somewhere!' Write-Host 'Base Source: '$BaseSource Write-Host 'Base Target: '$BaseTarget Write-Host 'Customer database: '$customerDB; Write-Host Write-Host Write-Host for ($i = 0; $i -lt 3; $i ++) { [System.Console]::Beep(1000, 500) [System.Console]::Beep(1500, 500) } break } Try { UW-CreateDirectory -DirectoryPath $WorkFolder UW-CreateDirectory -DirectoryPath $WorkFolder\$BaseSourceF UW-CreateDirectory -DirectoryPath $WorkFolder\$BaseTargetF UW-CreateDirectory -DirectoryPath $WorkFolder\$CustomerDBF UW-CreateDirectory -DirectoryPath $WorkFolder\Result } Catch { Write-Host 'Error: '$_ for ($i = 0; $i -lt 3; $i ++) { [System.Console]::Beep(1000, 500) [System.Console]::Beep(1500, 500) } break } $popup = new-object -comobject wscript.shell Write-Progress -activity "Upgrade Wizard" -status "Step $counter1 of $total (Getting object differences between Customer DB and Base Source)" -PercentComplete (($counter1 / $total) * 100); $counter1 += 1; $DiffArray1 = Invoke-TFFolderDiffUW -SourceFolder $CustomerDB -TargetFolder $BaseSource Write-Progress -activity "Upgrade Wizard" -status "Step $counter1 of $total (Getting object differences between Base Source and Base Target)" -PercentComplete (($counter1 / $total) * 100); $counter1 += 1; $DiffArray2 = Invoke-TFFolderDiffUW -SourceFolder $BaseSource -TargetFolder $BaseTarget Write-Progress -activity "Upgrade Wizard" -status "Step $counter1 of $total (Preparing object list to download)" -PercentComplete (($counter1 / $total) * 100); $counter1 += 1; $ObjToDownload = New-Object System.Collections.Generic.List[System.String] foreach($DiffItem in $DiffArray2) { $ObjToDownload.Add($DiffItem) } foreach ($DiffItem in $DiffArray1) { if(!$ObjToDownload.contains($DiffItem)) { $ObjToDownload.Add($DiffItem); } } Try { if(($SkipQuestions -eq 'False') -or ($SkipQuestions -eq '')) {$intAnswer = $popup.popup("Do you want to download CURRENT Base objects?", 0,"Download objects",4)} else {$intAnswer = 6} If ($intAnswer -eq 6) { $counter2 = 1 foreach ($DItem in $ObjToDownload) { $total2 = $ObjToDownload.count; Write-Progress -activity "Base Source" -status "Files $counter2 of $total2" -PercentComplete (($counter2 / $total2) * 100); Get-ObjectsFromTFSBranch -BranchPath "$BaseSource/$DItem" -DestinationPath $WorkFolder\$BaseSourceF\$DItem -Type File $counter2 += 1; } } if(($SkipQuestions -eq 'False') -or ($SkipQuestions -eq '')) {$intAnswer = $popup.popup("Do you want to download TARGET Base objects?", 0,"Download objects",4) } else {$intAnswer = 6} If ($intAnswer -eq 6) { $counter2 = 1 foreach ($DItem in $ObjToDownload) { $total2 = $ObjToDownload.count; Write-Progress -activity "Base Source" -status "Files $counter2 of $total2" -PercentComplete (($counter2 / $total2) * 100); Get-ObjectsFromTFSBranch -BranchPath "$BaseTarget/$DItem" -DestinationPath $WorkFolder\$BaseTargetF\$DItem -Type File $counter2 += 1; } } if(($SkipQuestions -eq 'False') -or ($SkipQuestions -eq '')) {$intAnswer = $popup.popup("Do you want to download Customer Database objects?", 0,"Download objects",4) } else {$intAnswer = 6} If ($intAnswer -eq 6) { $counter2 = 1 foreach ($DItem in $ObjToDownload) { $total2 = $ObjToDownload.count; Write-Progress -activity "Base Source" -status "Files $counter2 of $total2" -PercentComplete (($counter2 / $total2) * 100); Get-ObjectsFromTFSBranch -BranchPath "$CustomerDB/$DItem" -DestinationPath $WorkFolder\$CustomerDBF\$DItem -Type File $counter2 += 1; } } } Catch { Write-Host 'Error: '$_ for ($i = 0; $i -lt 3; $i ++) { [System.Console]::Beep(1000, 500) [System.Console]::Beep(1500, 500) } break; } $counter1 += 1; $collection = @() Write-Progress -activity "Upgrade Wizard" -status "Step $counter1 of $total (Upgrade)" -PercentComplete (($counter1 / $total) * 100); Try { if(($SkipQuestions -eq 'False') -or ($SkipQuestions -eq '')) {$intAnswer = $popup.popup("Do you want to do the upgrade process?", 0,"Upgrade",4) } else {$intAnswer = 6} If ($intAnswer -eq 6) { $collection = Merge-NAVObjectsWithPropertiesUW -workFolder $WorkFolder -sourceBaseFolder $BaseSourceF -sourceModFolder $CustomerDBF -targetBaseFolder $BaseTargetF -resultFolder Result } } Catch { Write-Host 'Error: '$_ for ($i = 0; $i -lt 3; $i ++) { [System.Console]::Beep(1000, 500) [System.Console]::Beep(1500, 500) } break; } $summary = @() $path = "$WorkFolder\Result\" $TotalNoOfObj = 0 $TotalNoOfConfObj = 0 $TotalNoOfConf = 0 $TotalTime = 0 $FixTimes = @(("Codeunit", 5), ("XMLPort", 5), ("Query", 5), ("MenuSuite", 7), ("Page", 10), ("Report", 8), ("Table", 4)) foreach ($obj in $collection) { $short = $obj.ObjectName.Substring(0,3) $ObjTotal = (dir $path"$short*.TXT" | measure).Count $ObjConflicted = (dir $path"$short*.CONFLICT" | measure).Count $minutes = 0 foreach ($min in $FixTimes) { if ($min[0] -eq $obj.ObjectName) { $minutes = $min[1] } } $out = new-object psobject $out | add-member noteproperty "Object Name" $obj.ObjectName $out | add-member noteproperty "No of objects" $ObjTotal; $out | add-member noteproperty "No of conflicted objects" $ObjConflicted; $out | add-member noteproperty "No of conflicts" $obj.Total; $out | add-member noteproperty "Minutes to fix 1 conflict" $minutes; [decimal]$linetime = $obj.Total $linetime = $linetime * $minutes; $out | add-member noteproperty "Total minutes" $linetime $summary += $out $TotalNoOfObj += $ObjTotal $TotalNoOfConfObj += $ObjConflicted $TotalNoOfConf += $obj.Total $TotalTime += $linetime } $out = new-object psobject $lineSep = '----------' $out | add-member noteproperty "Object Name" $lineSep $out | add-member noteproperty "No of objects" $lineSep $out | add-member noteproperty "No of conflicted objects" $lineSep $out | add-member noteproperty "No of conflicts" $lineSep $out | add-member noteproperty "Minutes to fix 1 conflict" $lineSep $out | add-member noteproperty "Total minutes" $lineSep $summary += $out $out = new-object psobject $out | add-member noteproperty "Object Name" ">> TOTAL <<" $out | add-member noteproperty "No of objects" $TotalNoOfObj $out | add-member noteproperty "No of conflicted objects" $TotalNoOfConfObj $out | add-member noteproperty "No of conflicts" $TotalNoOfConf $out | add-member noteproperty "Minutes to fix 1 conflict" "Minutes:" $out | add-member noteproperty "Total minutes" $TotalTime $summary += $out $out = new-object psobject $out | add-member noteproperty "Object Name" " " $out | add-member noteproperty "No of objects" " " $out | add-member noteproperty "No of conflicted objects" " " $out | add-member noteproperty "No of conflicts" " " $out | add-member noteproperty "Minutes to fix 1 conflict" "Hours:" $hours = [math]::Round($TotalTime/60, 1) $out | add-member noteproperty "Total minutes" $hours $summary += $out $out = new-object psobject $out | add-member noteproperty "Object Name" " " $out | add-member noteproperty "No of objects" " " $out | add-member noteproperty "No of conflicted objects" " " $out | add-member noteproperty "No of conflicts" " " $out | add-member noteproperty "Minutes to fix 1 conflict" "Days:" [decimal]$daypart = (($hours/7) % 1) [decimal]$daypart2 = 0 if ($daypart -lt 0.5) { $daypart2 = 0.5 } else { $daypart2 = 1 } [decimal]$days2 = [math]::Floor($hours/7) + $daypart2 $out | add-member noteproperty "Total minutes" $days2 $summary += $out Write $summary |Out-GridView } function UW-Get-TFSFolders ( [Parameter(Mandatory=$false)] [string]$LevelPath, [Parameter(Mandatory=$false)] [string]$Desc, [Parameter(Mandatory=$false)] [int]$Level ) { Add-Type -Assembly Microsoft.VisualBasic $ItemCollection = New-Object System.Collections.Generic.List[System.String] $ItemDictionary = New-Object "System.Collections.Generic.Dictionary``2[System.Int32, System.String]" [string] $URLString = ''; if ($LevelPath -ne '') { $URLString = '_apis/tfvc/items?scopePath=' + $LevelPath + '&recursionLevel=OneLevel&isFolder=true' } else { $URLString = "_apis/tfvc/items?recursionLevel=OneLevel&isFolder=true" } $Folders = Invoke-TFSAPIUW -Url $URLString [int]$num = 1; [bool]$isFound = 0; [int]$Lines = 10; [int]$counter = 0; [int]$inputInt = 0; foreach ($Folder in $Folders.value) { if (($Folder.IsFolder) -and ($Folder.path -ne $LevelPath)) { if (($Folder.path -notlike '*$/Addition*') -and ($Folder.path -notlike '*$/Mobile Apps*') -and ($Folder.path -notlike '*BuildProcessTemplates*') ` -and ($Folder.path -notlike '$/')) { $ItemCollection.Add($Folder.path); } } } $ItemCollection.Sort(); foreach ($SItem in $ItemCollection) { $ItemDictionary.Add($num, $SItem); $num = $num + 1; $isFound = 1; } $PickValue = $ItemDictionary| Out-GridView -Title $Desc -OutputMode Single [string]$tmpVal = $PickValue.Key; if ($tmpVal -eq '') { write-host 'Canceled by the user' break } else { $inputInt = [int]$tmpVal; } $errInput = 0; while($errInput -eq 0) { IF ($isFound -ne 0) { if ($inputInt -eq '') { if ((-not [Microsoft.VisualBasic.Information]::IsNumeric($inputInt)) -or ($inputInt -eq '')) { $inputInt = 0 } } if ($level -lt 1) { if (([int]$inputInt -gt 0) -and ([int]$inputInt -le $ItemCollection.Count)) { $errInput = 1 $level = $Level + 1; UW-Get-TFSFolders -LevelPath $ItemCollection[$inputInt-1] -Desc "details..." -Level $level } else { $inputInt = 0 } } else { if (([int]$inputInt -gt 0) -and ([int]$inputInt -le $ItemCollection.Count)) { $errInput = 1 #return $LevelPath return $ItemCollection[$inputInt-1] } else { $inputInt = 0 } } } else { $errInput = 1; } } } function UW-RemoveCharFromString ( [Parameter(Mandatory=$true)] [string]$Text ) { $Text = $Text.Replace('/', '').Replace('$','').Replace(' ', '').Replace('-', '') return $Text } Function UW-CreateDirectory { Param( [Parameter(Mandatory=$true)] [string]$DirectoryPath ) [IO.Directory]::CreateDirectory($DirectoryPath) | Out-Null } Export-ModuleMember -Function UpgradeWizard |