如何检查 PowerShell 配置文件脚本是否正在从 SSH 会话运行?

问题描述 投票:0回答:1

我正在尝试解决 Win32-OpenSSH 中的 bug,其中使用 pwsh.exe(核心)并通过 SSH/SCP 远程登录时不考虑

-NoProfile -NoLogo
。我尝试过的一种方法(多种方法)是在我的
Microsoft.PowerShell_profile.ps1
个人资料的开头添加以下内容。

function IsInteractive {
    $non_interactive = '-command', '-c', '-encodedcommand', '-e', '-ec', '-file', '-f'
    -not ([Environment]::GetCommandLineArgs() | Where-Object -FilterScript {$PSItem -in $non_interactive})
}
# No point of running this script if not interactive
if (-not (IsInteractive)) {
    exit
}
...

但是,这不适用于远程 SSH,因为当将

[Environment]::GetCommandLineArgs()
与 pwsh.exe 一起使用时,您得到的只是:
C:\Program Files\PowerShell\6\pwsh.dll
无论您是否处于交互式会话中。

我尝试的另一种方法是扫描进程树并查找

sshd
父级,但这也没有结论,因为它可能在另一个线程中运行,其中找不到
sshd
作为父级。 所以后来我尝试寻找其他东西。例如
conhost
。但是在一台机器上
conhost
pwsh
之前开始,而在另一台机器上,它在…之后开始,然后你需要扫描树并可能找到一个资源管理器实例,在这种情况下,它只是前一个的积极因素进程是交互式的,但不是明确的非交互式当前进程会话。

function showit() {
    $isInter = 'conhost','explorer','wininit','Idle',
    $noInter = 'sshd','pwsh','powershell'
    $CPID = ((Get-Process -Id $PID).Id)

    for (;;) {
        $PNAME = ((Get-Process -Id $CPID).Name) 
        Write-Host ("Process: {0,6} {1} " -f $CPID, $PNAME) -fore Red -NoNewline
        $CPID = try { ((gwmi win32_process -Filter "processid='$CPID'").ParentProcessId) } catch { ((Get-Process -Id $CPID).Parent.Id) } 
        
        if ($PNAME -eq "conhost") {
            Write-Host ": interactive" -fore Cyan
            break;
        }
        if ( ($PNAME -eq "explorer") -or ($PNAME -eq "init") -or ($PNAME -eq "sshd") ) {
            # Write-Host ": non-interactive" -fore Cyan
            break;
        }
        ""
    }
}

如何检查配置文件脚本是否正在远程 SSH 会话中运行?

我为什么要这样做?因为我想禁止脚本通过 SSH/SCP/SFTP 自动运行,同时仍然能够手动运行它(仍然通过 SSH)。在 Bash 中,这是一个简单的单行代码。


一些相关(但无用)的答案:

powershell ssh openssh powershell-remoting
1个回答
0
投票

如果我理解正确的话,我相信我正在通过检查

[System.Console]::IsOutputRedirected
的值在我的 Powershell 配置文件中处理这种情况。

我在

Microsoft.Powershell_profile.ps1
中有一堆代码,我只想在交互式会话中运行,无论是在本地启动还是通过 SSH 启动。

即。当我在远程 Windows 主机上通过 SSH 运行命令时,如下所示:

ssh user@winhost C:\\PROGRA~1\PowerShell\7\pwsh.exe -Command Get-ChildItem

这会在运行命令之前自动执行我的 PowerShell 配置文件

Microsoft.Powershell_profile.ps1
。在我的 PowerShell 配置文件中,我检查
[System.Console]::IsOutputRedirected
的值,在本例中返回 true,然后我提前返回并跳过执行用于初始化 PowerShell 以进行交互式会话(交互式命令完成等)的代码。

相反,当我以交互方式 SSH 进入远程 Windows 主机上的 PowerShell 时,如下所示:

ssh user@winhost C:\\PROGRA~1\PowerShell\7\pwsh.exe

这也会自动执行我的 PoweShell 配置文件

Microsoft.Powershell_profile.ps1
,但在这种情况下,当我检查
[System.Console]::IsOutputRedirected
的值时,它返回 false,并且我允许脚本继续运行以设置我的 PowerShell 配置文件以进行交互式会话。

注意: 上述逻辑处理通过 SSH 执行时的特定情况,但是,为了处理以交互方式运行 PowerShell 的各种不同可能方式,我必须检查其他情况。我当前处理有关交互性的所有可能情况的逻辑如下:

if ([System.Console]::IsOutputRedirected -or [Environment]::UserInteractive -or !!([Environment]::GetCommandLineArgs() | Where-Object { $_ -ilike '-noni*' })) {
    // Non-Interactive
}
© www.soinside.com 2019 - 2024. All rights reserved.