param([string]$Root='C:\dev\autodesk\link',[string]$Out='C:\dev\autodesk\migration\inventory\plant3d-plugin-purpose') $ErrorActionPreference='SilentlyContinue' New-Item -ItemType Directory -Force -Path $Out,(Join-Path $Out 'evidence') | Out-Null $files=Get-ChildItem -LiteralPath $Root -Recurse -Force -File -ErrorAction SilentlyContinue $text=$files|Where-Object {$_.Extension.ToLower() -in '.cs','.vb','.fs','.csproj','.vbproj','.vcxproj','.sln','.slnx','.xml','.config','.json','.txt','.md','.user','.props','.targets'} $src=$text|Where-Object {$_.Extension.ToLower() -in '.cs','.vb','.fs'} function Csv($n,$r){$r|Export-Csv -LiteralPath (Join-Path $Out $n) -NoTypeInformation -Encoding UTF8} function Rel($p){$p.Substring($Root.Length).TrimStart('\')} function Canon($n){$n -replace '(?i)\s+v\.?\s*[0-9].*$','' -replace '(?i)\s+version\s*[0-9].*$','' -replace '\s+\(old\)$','' -replace '\s+—.*$','' -replace '\s+$',''} function FirstFamily($p){foreach($part in $p.Substring($Root.Length).TrimStart('\').Split('\')){if($part -match '^(?i:P_|P3D)'){return (Canon $part)}}; 'OUT_OF_SCOPE'} $dirs=Get-ChildItem -LiteralPath $Root -Recurse -Force -Directory -ErrorAction SilentlyContinue|Where-Object {$_.Name -match '^(?i:P_|P3D)' -and $_.FullName -notmatch '\\(bin|obj|\.vs|\.git|Files|FilesRelease|Libraries)(\\|$)'} $familyRows=@(); foreach($d in $dirs){$f=FirstFamily $d.FullName;if($f -eq (Canon $d.Name)){$familyRows += [pscustomobject]@{family=$f;path=(Rel $d.FullName);is_root_candidate='yes'}}};$familyRows=$familyRows|Sort-Object family,path -Unique $families=$familyRows|Select-Object -Expand family -Unique $status=@{'P_Rec_Annot'='KEEP_REDESIGN';'P_Rec_Update'='KEEP_REDESIGN';'P_Rec_Spec'='KEEP_REDESIGN';'P3DCorrectBoltsetLengths'='BUG_WORKAROUND_RETEST';'P3DGetBoltsetReport'='OFFICIAL_RESEARCH_REQUIRED';'P_Exp_EquipToRevit'='OFFICIAL_RESEARCH_REQUIRED';'P_Exp_ToRevit_MS'='OFFICIAL_RESEARCH_REQUIRED';'P_Exp_ToHydra'='REVIEW_USAGE';'P_Exp_ToInsul'='REVIEW_USAGE';'P_Exp_To5DSmeta'='REVIEW_USAGE';'P_Exp_ToStart'='REVIEW_USAGE';'P_Imp_FromPTH'='KEEP_REDESIGN';'P_Serv_ActualizeProjectBySpec'='KEEP_REDESIGN';'P_Serv_UpdateLinearWeight'='KEEP_REDESIGN';'P_Serv_CompP3D'='KEEP_REDESIGN';'P_Serv_UpSpecs'='KEEP_REDESIGN';'P3DUpdateFixedPipeLengths'='BUG_WORKAROUND_RETEST';'P3DUpdateFlanges'='BUG_WORKAROUND_RETEST';'P3DUpdateValves'='BUG_WORKAROUND_RETEST';'P3DCreateIsoBOM'='OFFICIAL_RESEARCH_REQUIRED';'P3DPlotToPdfIsoMasterfile'='REVIEW_USAGE';'P3DSetLayerForViewport'='REVIEW_USAGE';'P3DCommands'='KEEP_REDESIGN';'P3DDeleteNewLineInValues'='BUG_WORKAROUND_RETEST';'P3DCheckProject'='KEEP_REDESIGN';'P3DEnumerateSupports'='KEEP_REDESIGN';'P3DSelectComponents'='REVIEW_USAGE';'P3DGetPnPId'='REVIEW_USAGE';'P3DGetReportNew'='OFFICIAL_RESEARCH_REQUIRED'} $purpose=@{'P_Rec_Annot|AnnotateLineNumbers'='Batch line-number annotations in Ortho drawings';'P_Rec_Annot|AutoAnnotateView'='Automatic annotation update in viewport';'P_Rec_Annot|AutoElevation'='Automatic elevation annotations';'P_Rec_Annot|AutoLinenumberConnections'='Link line-number annotations to Ortho objects/connectors';'P_Rec_Annot|CheckOrthoView'='Detect missing or inconsistent objects in an Ortho view';'P_Rec_Annot|GetComponentGeometry'='Read Plant component geometry and parameters';'P_Rec_Annot|GetLinenumberAnnotationText'='Build line-number annotation text from PnP data';'P_Rec_Annot|InsertElevation'='Insert elevation annotation in Ortho';'P_Rec_Annot|OrthoAutoAnnotate'='Automatic Ortho annotations and dimensions';'P_Rec_Annot|OrthoLoader'='Loader/ribbon for Ortho tools';'P_Rec_Annot|P3DCopyMissingObjectsToOrthoDrawing'='Copy missing 3D objects to an Ortho drawing';'P_Rec_Annot|P3DSetLayerForViewport'='Set layer for an Ortho viewport';'P_Rec_Annot|PHPAnnotations'='Extended/batch Plant annotation processing';'P_Rec_Annot|SwapAttributesMenuItem'='Change annotation attributes/menu action';'P_Rec_Annot|UpdateOrthoDrawings'='Update Ortho drawing/toolset modules';'P_Rec_Annot|UpdateOrthoViewBlocks'='Update Ortho view blocks';'P_Rec_Update|P_Rec_Update'='Update Plant/PnP data, including flanges and XML/CSV settings';'P_Rec_Spec|AddTracingPipeRecords'='Add tracing records to specs/catalog data';'P_Rec_Spec|ResetLostBoltSetsAndGaskets'='Restore lost bolt-set/gasket records';'P_Rec_Spec|UpdateBoltSets'='Mass update bolt-set records';'P_Rec_Spec|SetComponentGroup'='Mass assign component groups';'P_Rec_Spec|EditProjectProperties'='Edit Plant project properties';'P3DCorrectBoltsetLengths|P3DCorrectBoltsetLengths'='Correct bolt-set length from Plant/PnP data';'P3DGetBoltsetReport|P3DGetBoltsetReport'='Produce a bolt-set report';'P_Exp_EquipToRevit|P_Exp_EquipToRevit'='Export equipment/Plant data to a Revit workflow';'P_Exp_ToRevit_MS|P_Exp_ToRevit_MS'='Export Plant/AutoCAD data to Revit';'P_Exp_ToHydra|P_Exp_ToHydra'='Export data to corporate Hydra workflow';'P_Exp_ToInsul|P_Exp_ToInsul'='Export data to corporate Insul workflow'} $rows=@();foreach($f in $families){$p=$familyRows|? family -eq $f|select -First 1;$rows += [pscustomobject]@{family=$f;module='__family__';canonical_source_path=$p.path;latest_probable_version='not established';component_type='mixed/unknown';user_command='not established';purpose=if($purpose.ContainsKey("$f|$f")){$purpose["$f|$f"]}else{'Not proven at family level; see modules and evidence'};user_workflow='not confirmed';input='Plant project/drawing or external data';output='drawing/data/report; varies';data_modified='possible';autodesk_api_area='see plugin-modules.csv';custom_dependencies='see plugin-modules.csv';native_2026_candidate='not established';native_difference='OFFICIAL_RESEARCH_REQUIRED';primary_status=if($status.ContainsKey($f)){$status[$f]}else{'UNKNOWN'};business_criticality='unknown';migration_complexity='high';evidence_confidence='weak';runtime_test='required';source_evidence=$p.path;official_source_reference='official-sources.md';notes='Copies/releases are not separate families'}} $manual='AnnotateLineNumbers','AutoAnnotateView','AutoElevation','AutoLinenumberConnections','CheckOrthoView','GetComponentGeometry','GetLinenumberAnnotationText','InsertElevation','OrthoAutoAnnotate','OrthoLoader','P3DCopyMissingObjectsToOrthoDrawing','P3DSetLayerForViewport','PHPAnnotations','SwapAttributesMenuItem','UpdateOrthoDrawings','UpdateOrthoViewBlocks';foreach($m in $manual){$k="P_Rec_Annot|$m";$rows += [pscustomobject]@{family='P_Rec_Annot';module=$m;canonical_source_path='P_Rec_Annot\v1.0.2\repo\'+$m;latest_probable_version='v1.0.4 repo/release family';component_type='DLL/library';user_command='see code-markers.csv';purpose=$purpose[$k];user_workflow='Open Ortho drawing and invoke command or loader';input='Ortho DWG and Plant PnP data';output='annotations, view blocks, copied/highlighted objects';data_modified='drawing and/or linked Ortho data';autodesk_api_area='AutoCAD API + Plant DataLinks/ProjectManager/Ortho';custom_dependencies='shared P_Rec_Annot modules';native_2026_candidate='Ortho Generation, Ortho Annotate, annotation styles, project setup';native_difference='Official docs confirm core functions, not exact batch logic';primary_status='KEEP_REDESIGN';business_criticality='important';migration_complexity='high';evidence_confidence='confirmed';runtime_test='load command and compare single/multi-view output';source_evidence='P_Rec_Annot\v1.0.2\repo\'+$m;official_source_reference='official-sources.md#ortho';notes='Static only'}} Csv 'plugin-families.csv' $familyRows;Csv 'plugin-purpose-matrix.csv' $rows $proj=@();foreach($f in $text|? Extension -in '.csproj','.vbproj','.vcxproj'){$fam=FirstFamily $f.FullName;if($fam -eq 'OUT_OF_SCOPE'){continue};$x=$null;try{$x=[xml](Get-Content -Raw -LiteralPath $f.FullName)}catch{};$pg=@($x.Project.PropertyGroup);$refs=@($x.Project.ItemGroup.Reference);$proj += [pscustomobject]@{family=$fam;module=$f.BaseName;source_path=(Rel $f.FullName);target_framework=(($pg|? TargetFrameworkVersion|select -First 1).TargetFrameworkVersion);platform_target=(($pg|? PlatformTarget|select -First 1).PlatformTarget);output_type=(($pg|? OutputType|select -First 1).OutputType);assembly_name=(($pg|? AssemblyName|select -First 1).AssemblyName);references=(($refs|% Include)-join '|');autodesk_refs=(($refs|? Include -match '(?i)acmgd|pnp|autodesk|processpower')|% Include)-join '|';sqlite=if(($refs|% Include)-match '(?i)sqlite'){'yes'}else{'no'};com=if(($refs|% Include)-match '(?i)interop|excel|word|com'){'possible'}else{'not observed'};source_present='yes'}};Csv 'plugin-modules.csv' ($proj|sort family,module,source_path) $dup=@();foreach($g in $familyRows|group family){foreach($r in $g.Group){$dup += [pscustomobject]@{family=$g.Name;path=$r.path;version_signal=if($r.path -match '(?i)release|repo|source|versions?|v[0-9]|old|archive|backup|prev'){$matches[0]}else{'none'};selection='latest probable version not runtime validated';duplicate_or_history=if($r.path -match '(?i)old|archive|backup|prev|versions?|release'){'possible'}else{'unknown'}}}};Csv 'duplicate-version-map.csv' $dup $ev=@();$sf=@();foreach($f in $src|? FullName -match '(?i)P_|P3D'){$m=Select-String -LiteralPath $f.FullName -Pattern '\[CommandMethod\s*\(\s*"([^"]+)' -CaseSensitive:$false;foreach($x in $m){$ev += [pscustomobject]@{file=(Rel $f.FullName);line=$x.LineNumber;kind='CommandMethod';detail=([regex]::Match($x.Line,'CommandMethod\s*\(\s*"([^"]+)').Groups[1].Value)}};$m2=Select-String -LiteralPath $f.FullName -Pattern 'IExtensionApplication|DllImport|DataLinksManager|PnPDatabase|ProjectParts\[|Tables\[|File\.Delete|Directory\.Delete|StreamWriter|Excel|Revit|Navisworks|Hydra|Insul' -CaseSensitive:$false;foreach($x in $m2){if($x.Line -match '(?i)password|passwd|pwd|token|secret|apikey|private key|connectionstring|user id|integrated security'){$sf += [pscustomobject]@{file=(Rel $f.FullName);line=$x.LineNumber;type='credential or connection-string keyword';risk='review';note='value omitted'}}else{$ev += [pscustomobject]@{file=(Rel $f.FullName);line=$x.LineNumber;kind='API/IO marker';detail=($x.Line -replace '\s+',' ')}}}};Csv 'evidence/code-markers.csv' $ev;Csv 'evidence/secret-findings.csv' $sf Set-Content -LiteralPath (Join-Path $Out 'source-root.md') -Encoding UTF8 -Value "# Source root`r`n`r`nRead-only source root: $Root`r`n`r`nlink is a symbolic link to the corporate UNC source. No source or binary files were copied." Set-Content -LiteralPath (Join-Path $Out 'official-sources.md') -Encoding UTF8 -Value @' # Official Autodesk sources used - https://help.autodesk.com/cloudhelp/2026/ENU/Plant3D-WhatsNew/files/GUID-384C71E7-9012-48B1-95B2-D4C42EBCF423.htm (What's New 2026/2026.1) - https://help.autodesk.com/cloudhelp/2026/ENU/Plant3D-WhatsNew/files/GUID-1D0F9938-E23A-4870-A4AB-E544701D20CB.htm (Spec Editor redesign) - https://help.autodesk.com/cloudhelp/2026/ENU/Plant3D-ReleaseNotes/files/AUTOCAD_PLNT3D_2026_RELEASE_NOTES.html (release notes) - https://help.autodesk.com/cloudhelp/2026/ENU/Plant3D-UserGuide/files/GUID-EEDF2AA7-B50B-484B-B47F-B48986A51C3D.htm (update multiple Ortho drawings) - https://help.autodesk.com/cloudhelp/2026/ENU/Plant3D-UserGuide/files/GUID-DAD70DC1-32F2-45E4-8685-0C574EF31299.htm (Ortho annotations) - https://help.autodesk.com/cloudhelp/2026/ENU/Plant3D-UserGuide/files/GUID-6D5E3975-53AA-4495-B727-BBB2B599B464.htm (annotation format/project setup) - https://help.autodesk.com/cloudhelp/2026/ENU/Plant3D-UserGuide/files/GUID-E0A54B13-5318-418B-B274-4D02673EC2ED.htm (calculated properties) - https://help.autodesk.com/view/PLNT3D/2026/ENU/?guid=GUID-6EF131FA-E852-4B8C-A21E-E2B2ED1016AC (Data Manager/Report Creator) - https://help.autodesk.com/cloudhelp/2026/ENU/Plant3D-UserGuide/files/GUID-7C60418E-3A86-47E0-ABED-1E5BB2F5C48A.htm (bolt length mapping) - https://help.autodesk.com/cloudhelp/2026/ENU/Plant3D-UserGuide/files/GUID-B82D8701-7101-428E-A475-7B093A36DF01.htm (piping connections/fasteners) - https://help.autodesk.com/cloudhelp/2026/ENU/Plant3D-SpecEditor/files/GUID-0B871505-A498-42C0-AAA7-B83A244CE5C4.htm (spec creation) '@ Set-Content -LiteralPath (Join-Path $Out 'plugin-dependency-graph.md') -Encoding UTF8 -Value @' # Plugin dependency graph Plant 3D/AutoCAD host -> custom loader or NETLOAD/APPLOAD workflow (runtime not confirmed) -> P_Rec_Annot Ortho modules -> Plant DataLinks/PnPDatabase/ProjectManager/Ortho assemblies. P_Rec_Update/P_Serv/P_Rec_Spec -> Plant managed API and/or SQLite/CSV/XML/Excel. P3D bolt/update/report families -> Plant PnP/spec/catalog/report data. P_Exp_* -> Revit/Navisworks/corporate outputs. Edges are static from project references and source markers; no DLL was loaded. '@ Set-Content -LiteralPath (Join-Path $Out 'retirement-candidates.md') -Encoding UTF8 -Value @' # Retirement candidates No component is approved for deletion from this static audit. - P3DGetBoltsetReport: likely overlaps Data Manager/Report Creator. Test field parity, grouping, formatting and totals before retiring only a duplicate. - P3DCreateIsoBOM/P3DGetReportNew: likely report/BOM functions; field-level comparison is required. - P3DSetLayerForViewport: project/viewport layer settings may cover part of the function; test inheritance and batch behavior. - P_Rec_Spec helpers: Spec/Catalog Editor, calculated properties and Report Creator may replace parts, but direct SQLite and corporate rules are not automatically covered. Required evidence: source command behavior, fixture before/after, official mapping, differences and runtime test in Plant 3D 2026/2026.1. '@ Set-Content -LiteralPath (Join-Path $Out 'migration-candidates.md') -Encoding UTF8 -Value @' # Migration candidates Highest priority redesign/port: P_Rec_Annot, P_Rec_Update, P_Serv_ActualizeProjectBySpec, P_Serv_UpdateLinearWeight, P_Serv_CompP3D, P_Rec_Spec and P_Imp_FromPTH. Targeted port/retest: P3DCorrectBoltsetLengths, P3DUpdateFixedPipeLengths, P3DUpdateFlanges, P3DUpdateValves, P3DDeleteNewLineInValues, P3DCommands and P3DEnumerateSupports. Architecture review: P_Exp_EquipToRevit, P_Exp_ToRevit_MS, P_Exp_ToHydra, P_Exp_ToInsul and P_Exp_To5DSmeta. '@ Set-Content -LiteralPath (Join-Path $Out 'runtime-tests-required.md') -Encoding UTF8 -Value @' # Runtime tests required 1. Load latest candidate in isolated Plant 3D 2026 and 2026.1; record command registration and errors. 2. Ortho: one view, multiple views/project, missing models, line-number/elevation/BOP annotations, layer inheritance and view-block update. 3. Bolt sets: standard/custom flange thickness, calculated length, mapping, gasket persistence and report totals. 4. Specs/catalogs: fixture comparison against Spec Editor/Catalog Editor, calculated properties, groups and no direct SQLite corruption. 5. Export/integration: Revit/Navisworks/IFC/Hydra/Insul schemas, units, errors, repeatability and offline behavior. 6. Safety: copies only, rollback, audit log, multi-user behavior and no production/network writes. '@ Set-Content -LiteralPath (Join-Path $Out 'official-research-required.md') -Encoding UTF8 -Value @' # Official research required Official sources confirm Ortho generation/update, annotation styles, Spec/Catalog Editor, calculated properties, bolt length mapping and Data Manager/Report Creator. They do not establish one-to-one replacements for corporate Hydra/Insul/Revit schemas, direct PnP/SQLite repair tools or every batch operation. Verify API compatibility of each referenced PnP/Ortho assembly, supported bolt repair automation, exact export schemas and supported batch annotation APIs. '@ Set-Content -LiteralPath (Join-Path $Out 'unknowns.md') -Encoding UTF8 -Value @' # Unknowns - Production-selected release DLL and loader/download list. - Actual usage frequency and business ownership. - Corporate acceptance criteria for Hydra/Insul/Revit/5DSmeta outputs. - Whether bolt/newline fixes reproduce on 2026/2026.1. - Whether direct SQLite operations remain supported for migrated projects. - Runtime load order, profiles, trusted paths and permissions. '@ $counts=($rows|Group-Object primary_status|Sort-Object Name|ForEach-Object {"- $($_.Name): $($_.Count)"}) -join "`r`n" $readme=@" # Functional inventory: Plant 3D plugin purpose Date: 2026-07-30. Read-only source: $Root. No EXE/DLL/ARX/DBX/LISP/PowerShell/BAT was run; no build/restore/SQL/runtime was performed. Unique normalized families: $($families.Count). Project/module rows: $($proj.Count). Raw candidate P_/P3D directories: $($dirs.Count). P_Rec_Annot is a confirmed Ortho annotation/DataLinks/PnP family and is classified KEEP_REDESIGN. P_Rec_Spec contains spec/catalog helpers and SQLite-oriented programs and is classified KEEP_REDESIGN. Bolt/update families are BUG_WORKAROUND_RETEST, not deletions. Report families may overlap Data Manager/Report Creator, but field parity is not proven. Revit/Hydra/Insul integrations remain research/review items. Status counts: $counts All classifications are static and do not approve deletion. See official-sources.md, evidence, retirement-candidates.md, migration-candidates.md, runtime-tests-required.md and unknowns.md. "@;Set-Content -LiteralPath (Join-Path $Out 'README.md') -Encoding UTF8 -Value $readme "Generated $(Get-Date -Format s)"|Set-Content -LiteralPath (Join-Path $Out 'evidence/generation.txt') -Encoding UTF8