Open icabraja opened 3 months ago
Hi @icabraja,
It's because New-Item
returns a value, and this is being returned from the scriptblock to Pode.Web which tries to parse it as an "Action".
If you pipe or set the value to null that should remove the warning :)
ie:
$null = New-Item -ItemType File -Force -Path "$PSScriptRoot\public\logs\deployment\$($WebEvent.Data.MACAddress).log"
While the output from New-Item
might be causing a pipeline issue here, I'm curious if you have any references to Save-PodeState
in the rest of your script. I found what I believe is a bug (#639) with PodeState not handling ScriptBlock
objects within $PodeContext.Server.State.'pode.web.pages'
. I've written a workaround function that should handle this unexpected behavior.
function Save-PodeStateInternal {
# "Save-PodeStateInternal called" | Out-Host
$PageCollection = [System.Collections.ArrayList]::new()
$Page = @{
Name = $null;
Value = $null
}
# Need to process $PodeContext.Server.State.'pode.web.pages'.Value collection
ForEach ($__page in $PodeContext.Server.State.'pode.web.pages'.Value.Keys) {
# $PodeContext.Server.State.'pode.web.pages'.Value."$__page" | Format-List | Out-Host
# "Processing '{0}'" -f $__page | Out-Host
if ($PodeContext.Server.State.'pode.web.pages'.Value."$__page".ScriptBlock) {
# "Processing '{0}' ScriptBlock property" -f $__page | Out-Host
$Page.Name = $__page
$Page.Value = $PodeContext.Server.State.'pode.web.pages'.Value."$__page".ScriptBlock
# "Adding to collection" | Out-Host
[void]$PageCollection.Add($Page)
$PodeContext.Server.State.'pode.web.pages'.Value."$__page".ScriptBlock = @{}
}
}
$null = Save-PodeState -Path $cache:PodeStateConfig
# Loop back through the collection restoring the running state
ForEach ($__page in $PageCollection) {
# "Restoring '{0}' ScriptBlock property" -f $__page.Name | Out-Host
$PodeContext.Server.State.'pode.web.pages'.Value.$($__page.Name).ScriptBlock = $__page.Value
}
}
However, unless I put this function directly within the Add-PodeRoute
scriptblock, the Function is not accessible anywhere else. I've declared it outside of Start-PodeServer
, inside Start-PodeServer
, with and without Export-ModuleMember
or even Export-PodeFunction
as shown in the Pode Functions documentation.
For example:
# The following code is stored in a ps1 file, and called from pwsh console
# Declaring Save-PodeStateInternal is NOT accessible within Start-PodeServer
Start-PodeServer {
# Declaring Save-PodeStateInternal IS accessible within Start-PodeServer but NOT within Add-PodeRoute or other Pode function ScriptBlocks.
# Get-Command -Name Save-PodeStateInternal returns the Command when declared within Start-PodeServer
# INIT AND NETWORK BINDING LOGIC HERE
Add-PodeRoute -Method Post -Path '/api/jobs/checkOut' -ScriptBlock {
function Save-PodeStateInternal {
$PageCollection = [System.Collections.ArrayList]::new()
$Page = @{
Name = $null;
Value = $null
}
# Need to process $PodeContext.Server.State.'pode.web.pages'.Value collection
ForEach ($__page in $PodeContext.Server.State.'pode.web.pages'.Value.Keys) {
if ($PodeContext.Server.State.'pode.web.pages'.Value."$__page".ScriptBlock) {
$Page.Name = $__page
$Page.Value = $PodeContext.Server.State.'pode.web.pages'.Value."$__page".ScriptBlock
[void]$PageCollection.Add($Page)
$PodeContext.Server.State.'pode.web.pages'.Value."$__page".ScriptBlock = @{}
}
}
$null = Save-PodeState -Path $cache:PodeStateConfig
# Loop back through the collection restoring the running state
ForEach ($__page in $PageCollection) {
$PodeContext.Server.State.'pode.web.pages'.Value.$($__page.Name).ScriptBlock = $__page.Value
}
}
$RequestBody = $WebEvent.Data
if ($RequestBody.Count -eq 0 -or $null -eq $RequestBody) {
Write-PodeJsonResponse -StatusCode 400 -Value @{ ErrorID = 'Invalid_Request_Body'; ErrorDescription = "The missing JobID and JobURL in request body." }
}
elseif (-not $RequestBody['JobID']) {
Write-PodeJsonResponse -StatusCode 400 -Value @{ ErrorID = 'Invalid_Request_Body'; ErrorDescription = "The missing JobID in request body." }
}
elseif (-not $RequestBody['JobURL']) {
Write-PodeJsonResponse -StatusCode 400 -Value @{ ErrorID = 'Invalid_Request_Body'; ErrorDescription = "The missing JobURL in request body." }
}
else {
Lock-PodeObject -ScriptBlock {
# LOGIC GOES HERE
Write-PodeJsonResponse -Value $Result
# Save the server state using the workaround
"Saving StateConfig with Save-PodeStateInternal." | Out-Host
Save-PodeStateInternal
}
}
}
}
Output from executing the script, then receiving HTTPS POST request from client:
[PS] C:\temp\pode> .\Start-PodeServer2.ps1
CommandType Name Version Source
----------- ---- ------- ------
Function Save-PodeStateInternal
Pode v2.11.1 (PID: 1088)
Get-Command:
Line |
3 | Get-Command -Name Save-PodeStateInternal | Out-Host
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| The term 'Save-PodeStateInternal' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
Setting PodeStateConfigFileLocation
Setting UploadFileDirectoryLocation
Attempting to restore pode state
Binding to <IPv4>
Binding to <IPv6>
Listening on the following 2 endpoint(s) [1 thread(s)]:
- https://<IPv4>:8443/
- https://<IPv6>:8443/
[Verbose]: [ContextId: 13d4a2b5-5ef6-59e5-0ab6-82acd923ef2b] Opening Receive
[Verbose]: [ContextId: 13d4a2b5-5ef6-59e5-0ab6-82acd923ef2b] Starting Receive
[Verbose]: [ContextId: 13d4a2b5-5ef6-59e5-0ab6-82acd923ef2b] Receiving request
[Verbose]: [ContextId: 13d4a2b5-5ef6-59e5-0ab6-82acd923ef2b] Received request
Saving StateConfig with Save-PodeStateInternal.
[Verbose]: [ContextId: 13d4a2b5-5ef6-59e5-0ab6-82acd923ef2b] Disposing Context
[Verbose]: [ContextId: 13d4a2b5-5ef6-59e5-0ab6-82acd923ef2b] Sending response
[Verbose]: [ContextId: 13d4a2b5-5ef6-59e5-0ab6-82acd923ef2b] Response sent
[Verbose]: [ContextId: 13d4a2b5-5ef6-59e5-0ab6-82acd923ef2b] Request disposed
[Verbose]: [ContextId: 13d4a2b5-5ef6-59e5-0ab6-82acd923ef2b] Response disposed
Date: 2024-11-13 13:11:21
Level: Error
ThreadId: 1
Server: Fileserver
Category: ObjectNotFound: (Save-PodeStateInternal:String) [Invoke-PodeScriptBlock], CommandNotFoundException
Message: The term 'Save-PodeStateInternal' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
StackTrace: at <ScriptBlock>, <No file>: line 566
at Invoke-PodeScriptBlock, C:\Program Files\PowerShell\Modules\Pode\2.11.1\Public\Utilities.ps1: line 584
at Lock-PodeObject<End>, C:\Program Files\PowerShell\Modules\Pode\2.11.1\Public\Threading.ps1: line 85
at <ScriptBlock>, <No file>: line 434
at Invoke-PodeScriptBlock, C:\Program Files\PowerShell\Modules\Pode\2.11.1\Public\Utilities.ps1: line 573
at <ScriptBlock>, <No file>: line 124
Date: 2024-11-13 13:11:21
Level: Error
ThreadId: 1
Server: Fileserver
Category: ObjectNotFound: (Save-PodeStateInternal:String) [], CommandNotFoundException
Message: The term 'Save-PodeStateInternal' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
StackTrace: at <ScriptBlock>, <No file>: line 566
at Invoke-PodeScriptBlock, C:\Program Files\PowerShell\Modules\Pode\2.11.1\Public\Utilities.ps1: line 584
at Lock-PodeObject<End>, C:\Program Files\PowerShell\Modules\Pode\2.11.1\Public\Threading.ps1: line 85
at <ScriptBlock>, <No file>: line 434
at Invoke-PodeScriptBlock, C:\Program Files\PowerShell\Modules\Pode\2.11.1\Public\Utilities.ps1: line 573
at <ScriptBlock>, <No file>: line 124
Date: 2024-11-13 13:11:21
Level: Error
ThreadId: 1
Server: Fileserver
Category: System.Management.Automation
Message: The term 'Save-PodeStateInternal' is not recognized as a name of a cmdlet, function, script file, or executable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
StackTrace: at System.Management.Automation.ExceptionHandlingOps.CheckActionPreference(FunctionContext funcContext, Exception exception)
at System.Management.Automation.Interpreter.ActionCallInstruction`2.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
I have created a page for adding my PXE deployments in the queue and everything works fine. Now I need to create a log file with new deployment but for some reason when I add
and click the button to add the deployment in the queue I get a warning in the console:
The page hangs, file gets created but button animation is in the loop and modal windows doesn't popup. Commenting out "New-Item", everything works fine. Here is a page snippet. Some data is redacted.
EDIT
Tried with piping empty string to Out-FiIe, empty string with redirect operator and finally Set-Content with empty string as a -Value, they all worked. Bug maybe?