InvokeExecuteNotebook.ps1
function Invoke-ExecuteNotebook { param( $InputNotebook, $OutputNotebook, [hashtable]$Parameters, [Switch]$Force, [Switch]$DoNotLaunchBrowser ) if (!$InputNotebook) { return } if ([System.Uri]::IsWellFormedUriString($InputNotebook, [System.UriKind]::Absolute)) { try { $data = Invoke-RestMethod $InputNotebook } catch { throw "$($InputNotebook) is not a valid Jupyter Notebook" } } else { $json = Get-Content $InputNotebook $data = $json | ConvertFrom-Json } [System.Collections.ArrayList]$cells = $data.cells $PSNotebookRunspace = New-PSNotebookRunspace if ($Parameters) { # $newVars = @("# override parameters") # $newVars += $( # foreach ($entry in $parameters.GetEnumerator() ) { # $quote = $null # $currentValue = $entry.value # if ($currentValue -is [string]) { $quote = "'" } # '${0} = {1}{2}{1}' -f $entry.name, $quote, $currentValue # } # ) # $newParams = New-CodeCell ($newVars -join "`r`n") | ConvertFrom-Json $source = @' # override parameters $payload = '{0}' | ConvertFrom-Json $names = $payload.psobject.Properties.name $names | foreach-object {{ Set-Variable -Name $_ -Value $payload.$_ }} Remove-Variable payload -ErrorAction SilentlyContinue Remove-Variable names -ErrorAction SilentlyContinue '@ -f ($parameters | ConvertTo-Json -Depth 3) $newParams = New-CodeCell $source | ConvertFrom-Json -Depth 3 $index = Get-ParameterInsertionIndex -InputNotebook $InputNotebook $cells.Insert($index, $newParams) } for ($idx = 0; $idx -lt $cells.count; $idx++) { $cell = $cells[$idx] if ($cell.cell_type -ne 'code') { continue } # Clear Errors $PSNotebookRunspace.PowerShell.Streams.Error.Clear() # Clear Commands $PSNotebookRunspace.PowerShell.Commands.Clear() $result = $PSNotebookRunspace.Invoke($cell.source) if ($PSNotebookRunspace.PowerShell.Streams.Error.Count -gt 0) { $text = $PSNotebookRunspace.PowerShell.Streams.Error | Out-String } else { $text = $result } $cell.outputs = @() if ($text) { $cell.outputs += [ordered]@{ name = "stdout" text = $text output_type = "stream" } } } $data.cells = $cells if ($OutputNotebook) { $isUri = Test-Uri $OutputNotebook if ($isUri) { if ($OutputNotebook.startswith("gist://")) { $OutFile = $OutputNotebook.replace("gist://", "") $targetFileName = Split-Path $OutFile -Leaf $contents = $data | ConvertTo-Json -Depth 4 $result = New-GistNotebook -contents $contents -fileName $targetFileName Write-Progress -Activity "Creating Gist" -Status $targetFileName if (!$DoNotLaunchBrowser -and $result) { Start-Process $result.html_url } } elseif ($OutputNotebook.startswith("abs://")) { if (Test-AzureBlobStorageUrl $outputNotebook) { $fullName = [System.IO.Path]::GetRandomFileName() ConvertTo-Json -InputObject $data -Depth 4 | Set-Content $fullName -Encoding utf8 try { $headers = @{'x-ms-blob-type' = 'BlockBlob' } Invoke-RestMethod -Uri ($OutputNotebook.Replace('abs', 'https')) -Method Put -Headers $headers -InFile $fullName } catch { throw $_.Exception.Message } finally { Remove-Item $fullName -ErrorAction SilentlyContinue } } } else { throw "Invalid OutputNotebook url '{0}'" -f $OutputNotebook } } else { if ((Test-Path $OutputNotebook) -and !$Force) { throw "$OutputNotebook already exists" } ConvertTo-Json -InputObject $data -Depth 4 | Set-Content $OutputNotebook -Encoding utf8 } } else { $data.cells.outputs.text } } |