InvokePowerShellNotebook.ps1
function Invoke-PowerShellNotebook { <# .SYNOPSIS Invoke-PowerShellNotebook executes all the PowerShell code blocks in a PowerShell Notebook. .Example Invoke-PowerShellNotebook .\SingleCodeBlock.ipynb Region Item TotalSold ------ ---- --------- South lime 20 West melon 76 #> param( [Parameter(ValueFromPipelineByPropertyName)] $NoteBookFullName, $OutFile, [Switch]$AsExcel, [Switch]$Show ) Process { if ($OutFile) { if (Test-Path $OutFile) { throw "$OutFile already exists" } $PSNotebookRunspace = New-PSNotebookRunspace $null = Copy-Item $NoteBookFullName $OutFile $notebookJson = Get-Content $OutFile | ConvertFrom-Json $codeCells = $notebookJson.cells | Where-Object { $_.'cell_type' -eq 'code' } foreach ($codeCell in $codeCells) { # Clear Errors $PSNotebookRunspace.PowerShell.Streams.Error.Clear() # Clear Commands $PSNotebookRunspace.PowerShell.Commands.Clear() $result = $PSNotebookRunspace.Invoke($codeCell.source) if ($PSNotebookRunspace.PowerShell.Streams.Error.Count -gt 0) { $text = $PSNotebookRunspace.PowerShell.Streams.Error | Out-String } else { $text = $result } $codeCell.outputs = @() $codeCell.outputs += [ordered]@{ name = "stdout" text = $text -join "`n" output_type = "stream" } } $PSNotebookRunspace.Close() $notebookJson | ConvertTo-Json -Depth 5 | Set-Content $OutFile -Encoding UTF8 } else { $codeBlocks = @(Get-NotebookContent $NoteBookFullName -JustCode) $codeBlockCount = $codeBlocks.Count $SheetCount = 0 for ($idx = 0; $idx -lt $codeBlockCount; $idx++) { $targetCode = $codeblocks[$idx].source Write-Progress -Activity "Executing PowerShell code block - [$(Get-Date)]" -Status (-join $targetCode) -PercentComplete (($idx + 1) / $codeBlockCount * 100) if ($AsExcel) { if (!(Get-Module -ListAvailable ImportExcel -ErrorAction SilentlyContinue)) { throw "This feature requires the ImportExcel PowerShell module. Use 'Install-Module -Name ImportExcel' to get it from the PS Gallery." } if ($idx -eq 0) { $notebookFileName = Split-Path $NoteBookFullName -Leaf $xlFileName = $notebookFileName -replace ".ipynb", ".xlsx" $xlfile = "{0}\{1}" -f $pwd.Path, $xlFileName Remove-Item $xlfile -ErrorAction SilentlyContinue } foreach ($dataSet in , @($targetCode | Invoke-Expression)) { if ($dataSet) { $SheetCount++ $uniqueName = "Sheet$($SheetCount)" Export-Excel -InputObject $dataSet -Path $xlfile -WorksheetName $uniqueName -AutoSize -TableName $uniqueName } } } else { , @($targetCode | Invoke-Expression) } } if ($AsExcel) { if ($Show) { Invoke-Item $xlfile } else { $xlfile } } } } } |