Skip to content

Commit 7ffbdec

Browse files
fix: wire staged TUI launcher flow (#367)
1 parent 98cae86 commit 7ffbdec

9 files changed

Lines changed: 197 additions & 26 deletions

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,15 @@ For the first real run:
5050
powershell.exe -NoLogo -NoProfile -ExecutionPolicy Bypass -File "$releaseRoot\Start-ShareSurfer.ps1" -Force
5151
```
5252

53-
It recursively unblocks ShareSurfer PowerShell files, imports the module, asks the first-run questions, asks whether to run intensive share-permission diagnostics before the scan, checks the `inputs` folder for ownership files, offers to build missing `ownership-enrichment.csv` evidence from CSVs, saves `sharesurfer-startup.config.json`, and writes `operator-assistant.plan.json` plus `operator-assistant-rerun.ps1`. In the interactive path it then offers to show those generated files and asks whether to run the generated diagnostic/scan/validate/dashboard script now. The run prompt defaults to No.
53+
It recursively unblocks ShareSurfer PowerShell files, imports the module, and opens the **ShareSurfer Start Menu**. From that menu you can review readiness, build ownership inputs, start the guided scan setup, validate exports, package the standalone dashboard, and review stop gates. The scan setup asks the first-run questions, asks whether to run intensive share-permission diagnostics before the scan, checks the `inputs` folder for ownership files, offers to build missing `ownership-enrichment.csv` evidence from CSVs, saves `sharesurfer-startup.config.json`, and writes `operator-assistant.plan.json` plus `operator-assistant-rerun.ps1`. In the interactive path it then offers to show those generated files and asks whether to run the generated diagnostic/scan/validate/dashboard script now. The run prompt defaults to No.
5454

5555
5. Choose the scan route: UNC path, `-ComputerName` and `-ShareName`, or `-SmbCollectionProvider NativeSmbRpc` when WinRM/CIM is blocked. The startup diagnostic path automatically checks whether a server-returned local path such as `C:\Public\Share` really exists on the collector; when it does not, ShareSurfer attempts the target UNC path instead and records that decision in `share-permission-diagnostics\share_permission_diagnostics.md` and `.csv`.
5656
6. Pick `-ObsAttribute`. The default is `extensionAttribute10`; some labs or smaller AD schemas may need another attribute such as `info`.
5757
7. Run the generated rerun script or `Invoke-ShareSurferScan`, then always run `Test-ShareSurferExport`.
5858
8. Open `report.html`, or package a real export with `scripts\New-ShareSurferStandaloneDashboard.ps1`.
5959
9. Review the stop gates before owner signoff or migration planning.
6060

61-
New operators should start with the [first-run guide](docs/first-run-guide.md) and keep the [command recipes](docs/command-recipes.md) nearby. For a guided console starting point, run `Start-ShareSurfer.ps1` from the release root or `Start-ShareSurferStartup` after importing the module. The startup flow writes a reusable JSON config and delegates to `Start-ShareSurferOperatorAssistant`; it does not collect data or change permissions until you review and run the generated rerun script. If `owner-mapping.csv` or `ownership-enrichment.csv` is missing, interactive startup can help build enrichment from candidate CSVs and can queue a post-scan `owner-mapping-draft.csv` for the first rerun.
61+
New operators should start with the [first-run guide](docs/first-run-guide.md) and keep the [command recipes](docs/command-recipes.md) nearby. For a guided console starting point, run `Start-ShareSurfer.ps1` from the release root; it opens the ShareSurfer Start Menu unless you supply `-ConfigPath` for startup replay. After importing the module, advanced operators can run `Start-ShareSurfer` for the same menu or `Start-ShareSurferStartup` to jump directly into startup config generation. The startup flow writes a reusable JSON config and delegates to `Start-ShareSurferOperatorAssistant`; it does not collect data or change permissions until you review and run the generated rerun script. If `owner-mapping.csv` or `ownership-enrichment.csv` is missing, interactive startup can help build enrichment from candidate CSVs and can queue a post-scan `owner-mapping-draft.csv` for the first rerun.
6262

6363
## Pause Before Owner Signoff
6464

@@ -77,7 +77,7 @@ Stop or document the gap before business-owner approval when any of these are tr
7777

7878
| Workflow | Commands and scripts |
7979
| --- | --- |
80-
| Guided first run | `Start-ShareSurfer.ps1`, `Start-ShareSurferStartup`, `Start-ShareSurferOperatorAssistant` |
80+
| Guided first run | `Start-ShareSurfer.ps1`, `Start-ShareSurfer`, `Start-ShareSurferStartup`, `Start-ShareSurferOperatorAssistant` |
8181
| Lab and fixture planning | `New-ShareSurferLabFixture`, `scripts\Invoke-ShareSurferLabValidation.ps1` |
8282
| Scan collection | `Invoke-ShareSurferScan` |
8383
| Optional readiness and diagnostics | `Invoke-ShareSurferOpenFileAssessment`, `Invoke-ShareSurferPortProtocolAssessment`, `Invoke-ShareSurferFileShareConnectivityAssessment`, `Invoke-ShareSurferSharePermissionDiagnostic` |

Start-ShareSurfer.ps1

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,21 @@ param(
44

55
[string] $SaveConfigPath = '',
66

7+
[string] $InputRoot = '',
8+
9+
[string] $ExportPath = '',
10+
11+
[string] $StandaloneDashboardPath = '',
12+
13+
[string] $ObsAttribute = 'extensionAttribute10',
14+
15+
[ValidateSet('Auto', 'ActiveDirectory', 'Ldap', 'DirectoryOnly')]
16+
[string] $AdLookupMode = 'Auto',
17+
718
[switch] $Interactive,
819

20+
[switch] $StartupOnly,
21+
922
[switch] $Force
1023
)
1124

@@ -92,8 +105,36 @@ if (-not (Test-Path -LiteralPath $modulePath -PathType Leaf)) {
92105

93106
Import-Module $modulePath -Force
94107

108+
if ([string]::IsNullOrWhiteSpace($InputRoot)) {
109+
$InputRoot = Join-Path $releaseRoot 'inputs'
110+
}
111+
112+
if ([string]::IsNullOrWhiteSpace($ExportPath)) {
113+
$ExportPath = Join-Path (Join-Path $releaseRoot 'exports') 'startup-scan'
114+
}
115+
116+
if ([string]::IsNullOrWhiteSpace($StandaloneDashboardPath)) {
117+
$StandaloneDashboardPath = Join-Path $ExportPath 'standalone-dashboard'
118+
}
119+
120+
if ([string]::IsNullOrWhiteSpace($ConfigPath) -and [string]::IsNullOrWhiteSpace($SaveConfigPath) -and -not $StartupOnly) {
121+
Start-ShareSurfer `
122+
-ReleaseRoot $releaseRoot `
123+
-InputRoot $InputRoot `
124+
-ExportPath $ExportPath `
125+
-StandaloneDashboardPath $StandaloneDashboardPath `
126+
-ObsAttribute $ObsAttribute `
127+
-AdLookupMode $AdLookupMode
128+
return
129+
}
130+
95131
$startupParams = @{
96132
ReleaseRoot = $releaseRoot
133+
InputRoot = $InputRoot
134+
ExportPath = $ExportPath
135+
StandaloneDashboardPath = $StandaloneDashboardPath
136+
ObsAttribute = $ObsAttribute
137+
AdLookupMode = $AdLookupMode
97138
}
98139

99140
if (-not [string]::IsNullOrWhiteSpace($ConfigPath)) {

docs/admin-ownership-import.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ During interactive mode, ShareSurfer walks one guided screen per field. Each scr
198198
Enter=accept | numbers=choose | type a header name | /text=filter | S=skip | B=back | ?=help | Q=quit
199199
```
200200

201-
Press Enter to accept the suggested header (or to move on when there is no suggestion), type a header's number or its name to map it, type `/` followed by text to narrow a long header list (for example `/mail`), press `S` to deliberately leave that ShareSurfer field blank, press `B` to go back and fix the previous field, or press `Q` to cancel without writing any files. If you type a header name that is not in the CSV, ShareSurfer says so on screen and records it as a warning in the saved mapping profile so it can be reviewed later.
201+
Press Enter to accept the suggested header. When there is no suggestion, ShareSurfer keeps you on that field and asks you to choose a numbered header, type a header name, filter with `/text`, or press `S` to deliberately leave that ShareSurfer field blank. Press `B` to go back and fix the previous field, or press `Q` to cancel without writing any files. If you type a header name that is not in the CSV, ShareSurfer says so on screen and records it as a warning in the saved mapping profile so it can be reviewed later.
202202

203203
## Step 3: Import A Normalized Ownership CSV
204204

docs/command-recipes.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ When run interactively, the startup script offers to show the generated JSON/pla
8181

8282
If `ownership-enrichment.csv` is missing, interactive startup can offer to launch the same `Join-ShareSurferOwnershipSources -Interactive -BrowseForCsv -IncludeContextGraph` workflow shown in Recipe 2A. That creates the enrichment, context graph, manifest, definition JSON, and reusable ownership import rerun script before startup continues. If `owner-mapping.csv` is missing, startup can add a post-scan `New-ShareSurferOwnerMappingDraft` step to the generated rerun script so the first scan can produce `owner-mapping-draft.csv` for an admin to fill and save as `owner-mapping.csv`.
8383

84-
The easiest release-root launcher is:
84+
The easiest release-root launcher opens the ShareSurfer Start Menu:
8585

8686
```powershell
8787
$releaseRoot = 'C:\ShareSurfer-0.1.0-pre.34'
@@ -91,6 +91,8 @@ $exportPath = 'C:\ShareSurfer\exports\finance-001'
9191
& "$releaseRoot\Start-ShareSurfer.ps1" -Force
9292
```
9393

94+
The menu shows readiness for ownership inputs, saved startup config, export validation, standalone dashboard packaging, and stop gates. Each menu entry previews the command it will run before asking for confirmation. If you want to replay an existing startup config without the menu, pass `-ConfigPath` to the same launcher.
95+
9496
If you already know the answers and want to generate the same files without prompts, import the module and call the startup command directly:
9597

9698
```powershell
@@ -206,7 +208,7 @@ This recipe creates three reusable files:
206208
- `normalized-ownership.csv`: canonical ownership rows for review.
207209
- `ownership-import-rerun.ps1`: reusable commands to retest the source and regenerate the normalized CSV without repeating the header interview.
208210

209-
If you need ShareSurfer to ask you about each header in the console, add `-Interactive` to `New-ShareSurferOwnershipMappingProfile`. The saved rerun file still uses the profile afterward. Interactive prompts show `Enter=accept/select | S=skip | B=back | ?=help | Q=quit`; use `B` to fix the previous field, `S` to intentionally leave a ShareSurfer field blank, and `?` for a reminder. When there is no suggestion and the source has fewer than 10 headers, Enter opens a small selector with arrow-key support where available and numbered fallback everywhere else.
211+
If you need ShareSurfer to ask you about each header in the console, add `-Interactive` to `New-ShareSurferOwnershipMappingProfile`. The saved rerun file still uses the profile afterward. Interactive prompts show `Enter=accept/select | S=skip | B=back | ?=help | Q=quit`; use `B` to fix the previous field, `S` to intentionally leave a ShareSurfer field blank, and `?` for a reminder. When there is no suggestion and the source has fewer than 10 headers, the prompt keeps the numbered header list on screen and asks you to choose a number, type a header name, or press `S` to skip deliberately.
210212

211213
To gather AD data from an HR or OBS file before scanning, create an enrichment CSV. ShareSurfer uses employee ID or employee number values from the source CSV to look up matching AD accounts when `-AdLookupMode Auto` or `ActiveDirectory` can read the directory. It fills available account, mail, title, office, manager, and OBS fields, then writes a local CSV that travels with the scan evidence.
212214

docs/first-run-guide.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ For a first useful scan:
1212
2. Use `C:\ShareSurfer-0.1.0-pre.34\` as `$releaseRoot`, or replace the version folder with the published prerelease you actually extracted.
1313
3. Run the recursive `Unblock-File` command in Step 1 before importing the module.
1414
4. Pick one known share and the correct `-ObsAttribute`.
15-
5. Recommended: run `Start-ShareSurfer.ps1` or `Start-ShareSurferStartup` to generate a reusable first-run JSON config, plan, and rerun script.
15+
5. Recommended: run `Start-ShareSurfer.ps1` to open the ShareSurfer Start Menu, then choose the guided scan setup when you are ready to generate a reusable first-run JSON config, plan, and rerun script. If you already know the startup command you want, you can still import the module and run `Start-ShareSurferStartup` directly.
1616
6. If HR, employee, OBS, project, or owner CSVs exist, let the startup prompts help build `ownership-enrichment.csv`, or normalize them before scanning with the ownership import commands.
1717
7. Run the collector, validate the export, and build `report.html`.
1818
8. Package the standalone dashboard from the validated export only when you need the richer local dashboard.

docs/ownership-csv-ingest-quick-reference.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ During interactive mode, ShareSurfer walks one guided screen per field, showing
7575
Enter=accept | numbers=choose | type a header name | /text=filter | S=skip | B=back | ?=help | Q=quit
7676
```
7777

78-
Press Enter to accept a suggestion, type a header's number or name to map it, type `/text` to filter a long header list, press `S` to intentionally leave a field blank, press `B` to go back and fix the previous field, or press `Q` to cancel without writing any files. A typed header that is not in the CSV is called out on screen and recorded as a warning in the saved mapping profile.
78+
Press Enter to accept a suggestion. When there is no suggestion, choose a numbered header, type a header name, type `/text` to filter a long header list, or press `S` to intentionally leave the field blank. Press `B` to go back and fix the previous field, or press `Q` to cancel without writing any files. A typed header that is not in the CSV is called out on screen and recorded as a warning in the saved mapping profile.
7979

8080
## 5. Normalize The CSV
8181

src/ShareSurfer/Public/Join-ShareSurferOwnershipSources.ps1

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,14 +1025,20 @@ function Invoke-ShareSurferOwnershipHeaderWizardCommand {
10251025

10261026
if ([string]::IsNullOrWhiteSpace($text)) {
10271027
if ([string]::IsNullOrWhiteSpace($suggested)) {
1028-
$State.FieldMap[$field] = ''
1029-
[void]$State.Skipped.Add($field)
1028+
$visible = @(Get-ShareSurferOwnershipHeaderWizardVisibleHeaders -State $State)
1029+
if ($visible.Count -gt 0 -and $visible.Count -le 10) {
1030+
$State.Message = ('No suggestion exists for {0}. Choose one of the numbered headers above, type a header name, or press S to skip deliberately.' -f $field)
1031+
}
1032+
else {
1033+
$State.Message = ('No suggestion exists for {0}. Type /text to filter, type a header name, or press S to skip deliberately.' -f $field)
1034+
}
1035+
return $State
10301036
}
10311037
return (Step-ShareSurferOwnershipHeaderWizard -State $State)
10321038
}
10331039

10341040
if ($upper -eq '?' -or $upper -eq 'HELP') {
1035-
$State.Message = ('{0} Type a header name or its number to map {1}, Enter to accept the suggestion, /text to filter the header list, S to skip, B to go back, Q to cancel.' -f (Get-ShareSurferOwnershipFieldExplanation -Field $field), $field)
1041+
$State.Message = ('{0} Type a header name or its number to map {1}, Enter to accept an existing suggestion, /text to filter the header list, S to skip, B to go back, Q to cancel.' -f (Get-ShareSurferOwnershipFieldExplanation -Field $field), $field)
10361042
return $State
10371043
}
10381044

0 commit comments

Comments
 (0)