Как получить значение переменной отсюда и использовать это значение для полезных дел а не для вывода в консоль

Product: PowerShell Studio 2024 (64 Bit)
Build: v5.8.237
OS: Windows 10.0.14393
PS Version: 5.1.14393.0, 7.4.1

Using powershell core 7.4.1, when I run the app via Run button app works fine, powershell-core windows logs records this event:

Changing back from Powershell7 to Powershell5 exe works fine.

Please advise. Happy to send you a test project to reproduce error.

@echo off&cls
setlocal enabledelayedexpansion
set working_directory=%~dp0
if %working_directory% NEQ %cd% (
set working_directory=%cd%
)
call chooser.bat :: Активируем выбор файла
set filename=!chose!
set "filename=%filename:~0,-12%" :: обрезка
echo Path to file %filename%
pause

Код для выбора файла.

<# : chooser.bat
:: launches a File... Open sort of file chooser and outputs choice(s) to the console
@echo off
setlocal enabledelayedexpansion
for /f "delims=" %%I in ('powershell -noprofile "iex (${%~f0} | out-string)"') do (
set "chose=%%~I"
echo !chose!
)
goto :EOF
: end Batch portion / begin PowerShell hybrid chimera #>
Add-Type -AssemblyName System.Windows.Forms
$f = new-object Windows.Forms.OpenFileDialog
$f.InitialDirectory = pwd
$f.Filter = "Program executable (program.exe)|program.exe"
$f.ShowHelp = $true
$f.Multiselect = $false
[void]$f.ShowDialog()
if ($f.Multiselect) { $f.FileNames } else { $f.FileName } 

I’m using powershell core 7.4.2 to run an own .Net module

[Reflection.Assembly]::LoadFile("C:\test\test.dll")
[Some.NameSpace.ClassName]::DoSth('...')

If test.dll is compiled for .Net Framework 4.8 this works as expected.

If test.dll is compiled for .Net 8.0 this fails. Fiddling around with Add-Type reveals a ReflectionTypeLoadException. Some parts of the assembly are missing

try
{ Add-Type -Path "C:\test\test.dll"
}
catch [System.Reflection.ReflectionTypeLoadException]
{ $e = $PSItem.Exception $e.LoaderExceptions
}

None of the listed assemblies in LoaderExceptions are used in my code (e.g. System.Text.RegularExpressions, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a) but more of interest is “System.Runtime, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a” which indicates to me that basically .Net 8 is not loaded at all.

I did some more tests by adding the assemblies in question System.Runtime.dll, System.Private.CoreLib.dll, System.Text.RegularExpressions.dll but gave up after the error that
“System.Object” of the assembly “System.Private.CoreLib” can not be found.

:/>  Как удалить запланированную задачу в Windows 10

test.dll does not include fancy usings:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Xml.XPath;
using Microsoft.Win32;
namespace Some.NameSpace
{ public static class ClassName { public static void DoSth(string fileName) { } }
}

What am I doing wrong?

Настал тот момент когда необходимо уходить от всех зарубежных программ удаленного подключения, во всяком случае у нас в компании. Посмотрев отечественные аналоги мы пришли в ужас от стоимости и качества работы ПО. Поразмыслив какой функционал нам необходим для подключения 1-линии к пользователям поняли:

  1. Список ПК к которым нужно подключиться

  2. Управление ПК без согласия пользователя

А значит нам будет достаточно простого powershell’a.

Для выполнения дальнейших действий необходимо установить модуль Active Directory для PowerShell

Add-Type -assembly System.Windows.Forms
$window_form = New-Object System.Windows.Forms.Form
$window_form.Text ='Подключение к удаленному рабочему столу'
$window_form.Width = 240
$window_form.Height = 550
$window_form.StartPosition = 'CenterScreen'
$FormLabel1 = New-Object System.Windows.Forms.Label
$FormLabel1.Text = "Введите логин:"
$FormLabel1.Location = New-Object System.Drawing.Point(10,10)
$FormLabel1.AutoSize = $true
$window_form.Controls.Add($FormLabel1)
$FormTextBox1 = New-Object System.Windows.Forms.TextBox
$FormTextBox1.Width = 200
$FormTextBox1.Location = New-Object System.Drawing.Point(10,25)
$FormLabel2 = New-Object System.Windows.Forms.Label
$FormLabel2.Text = "Введите пароль:"
$FormLabel2.Location = New-Object System.Drawing.Point(10,50)
$FormLabel2.AutoSize = $true
$FormTextBox2 = New-Object System.Windows.Forms.TextBox
$FormTextBox2.Width = 200
$FormTextBox2.text = $NULL
$FormTextBox2.Location = New-Object System.Drawing.Point(10,65)
$FormLabel3 = New-Object System.Windows.Forms.Label
$FormLabel3.Text = "Выберете компьютер для подключения:"
$FormLabel3.Location = New-Object System.Drawing.Point(10,90)
$FormLabel3.AutoSize = $true
$ListBox = New-Object System.Windows.Forms.ListBox
$ListBox.Width = 200
$ListBox.Height = 300
$ListBox.Location = New-Object System.Drawing.Point(10,105)
$FormButton = New-Object System.Windows.Forms.Button
$FormButton.Location = New-Object System.Drawing.Size(10,400)
$FormButton.Size = New-Object System.Drawing.Size(200,30)
$FormButton.Text = "Подключится"
$window_form.AcceptButton = $FormButton
$FormButton2 = New-Object System.Windows.Forms.Button
$FormButton2.Location = New-Object System.Drawing.Size(10,440)
$FormButton2.Size = New-Object System.Drawing.Size(200,30)
$FormButton2.Text = "Закрыть"
$window_form.CancelButton = $FormButton3
$FormButton2.Add_Click({$window_form.Close();$window_form.Visible=$false})
$FormLabel4 = New-Object System.Windows.Forms.Label
$FormLabel4.Text = ""
$FormLabel4.Location = New-Object System.Drawing.Point(10,480)
$FormLabel4.AutoSize = $true
$window_form.Controls.Add($FormButton)
$window_form.Controls.Add($FormButton2)
$window_form.Controls.Add($ListBox)
$window_form.Controls.Add($FormTextBox1)
$window_form.Controls.Add($FormTextBox2)
$window_form.Controls.Add($FormLabel1)
$window_form.Controls.Add($FormLabel2)
$window_form.Controls.Add($FormLabel3)
$window_form.Controls.Add($FormLabel4)
$window_form.Add_Shown({$FormTextBox1.Select()})
$window_form.Topmost = $true
$window_form.MaximizeBox = $false
$result = $window_form.ShowDialog()
# Прописываем ваш домен и имя пользователя
$FormTextBox1.text = "$Env:UserDomain\$Env:UserName"
# Поле пароля делаем скрытым
$FormTextBox2.PasswordChar = '*'
# Заполняем свой OU и домен
$OU = "OU=Computers,DC=domain,DC=local"
# Получаем список ПК и вносим его в поле выбора ПК
$comps = (Get-ADComputer -SearchBase $OU -Filter *).Name | Sort-Object
ForEach ($comp in $comps){ [void] $listBox.Items.Add($comp) }

Теперь нужно выполнить действие при нажатии на кнопку $FormButton в котором мы должны будем найти активный сеанс пользователя удаленного ПК и подключиться к этому сеансу

# Действие на нажатие кнопки
$FormButton.Add_Click({
# Получаем имя выбранного ПК из списка
$ps = $listBox.SelectedItem.ToString()
# Передаем логин и пароль в переменную
$pwsecur = ConvertTo-SecureString -String $FormTextBox2.text -AsPlainText -Force
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $FormTextBox1.text, $pwsecur
# Находим все сессии удаленного ПК и ищем активную $active_sessions = quser /server:$ps | foreach {($_ -replace "\s\s+",",")} | ConvertFrom-Csv ForEach ($active_session in $active_sessions) { #Не проверял работу на англ версии if (($active_session.СТАТУС -eq 'Активно') -or ($active_session.STATUS -eq 'Active')){ $id = $active_session.ID }
# Подключаемся к активной сессии
Start-Process -FilePath "mstsc" -ArgumentList "/v:$ps /shadow:$id /control /noconsentprompt" -Credential $Cred -Wait -WindowStyle Maximized

Скрипт готов, бежим проверять

:/>  Power shell командная строка при запуске пк включается и исчезает

Так же можем добавить проверки:

  1. Заполнено поле с паролем

С такими проверками полная версия скрипта будет выглядеть так

Hidden text
[Console]::outputEncoding = [System.Text.Encoding]::GetEncoding('cp866')
$OU = "OU=Computers,DC=domain,DC=local"
Add-Type -assembly System.Windows.Forms
$window_form = New-Object System.Windows.Forms.Form
$window_form.Text ='Подключение к удаленному рабочему столу'
$window_form.Width = 240
$window_form.Height = 550
$window_form.StartPosition = 'CenterScreen'
$FormLabel1 = New-Object System.Windows.Forms.Label
$FormLabel1.Text = "Введите логин:"
$FormLabel1.Location = New-Object System.Drawing.Point(10,10)
$FormLabel1.AutoSize = $true
$window_form.Controls.Add($FormLabel1)
$FormTextBox1 = New-Object System.Windows.Forms.TextBox
$FormTextBox1.Width = 200
$FormTextBox1.text = "$Env:UserDomain\$Env:UserName"
$FormTextBox1.Location = New-Object System.Drawing.Point(10,25)
$FormLabel2 = New-Object System.Windows.Forms.Label
$FormLabel2.Text = "Введите пароль:"
$FormLabel2.Location = New-Object System.Drawing.Point(10,50)
$FormLabel2.AutoSize = $true
$FormTextBox2 = New-Object System.Windows.Forms.TextBox
$FormTextBox2.Width = 200
$FormTextBox2.text = $NULL
$FormTextBox2.PasswordChar = '*'
$FormTextBox2.Location = New-Object System.Drawing.Point(10,65)
$FormLabel3 = New-Object System.Windows.Forms.Label
$FormLabel3.Text = "Выберете компьютер для подключения:"
$FormLabel3.Location = New-Object System.Drawing.Point(10,90)
$FormLabel3.AutoSize = $true
$ListBox = New-Object System.Windows.Forms.ListBox
$ListBox.Width = 200
$ListBox.Height = 300
$ListBox.Location = New-Object System.Drawing.Point(10,105)
$comps = (Get-ADComputer -SearchBase $OU -Filter *).Name | Sort-Object
ForEach ($comp in $comps){ [void] $listBox.Items.Add($comp) }
$FormButton = New-Object System.Windows.Forms.Button
$FormButton.Location = New-Object System.Drawing.Size(10,400)
$FormButton.Size = New-Object System.Drawing.Size(200,30)
$FormButton.Text = "Подключится"
$window_form.AcceptButton = $FormButton
$FormButton.Add_Click({ $ps = $listBox.SelectedItem.ToString() If (($FormTextBox2.text).Length -gt 1){ If ($ps -ne $NULL){ Function Test-ADAuthentication { param($username,$password) (new-object directoryservices.directoryentry "",$username,$password).psbase.name -ne $null } $testcred = Test-ADAuthentication $FormTextBox1.text $FormTextBox2.text If ($testcred -eq 'True'){ If (Test-Connection $ps -Count 1 -Quiet){ $FormLabel4.Text = "Подключаемся..." $pwsecur = ConvertTo-SecureString -String $FormTextBox2.text -AsPlainText -Force $cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $FormTextBox1.text, $pwsecur Invoke-Command –ComputerName $ps -Credential $cred –ScriptBlock {New-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services' -Name 'Shadow' -Value '2' -PropertyType 'DWord'} Invoke-Command –ComputerName $ps -Credential $cred –ScriptBlock {New-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services' -Name 'AllowRemoteRPC' -Value '1' -PropertyType 'DWord'} $active_sessions = quser /server:$ps | foreach {($_ -replace "\s\s+",",")} | ConvertFrom-Csv ForEach ($active_session in $active_sessions) { #вот тут не знаю как будет на анг языке if (($active_session.СТАТУС -eq 'Активно') -or ($active_session.STATUS -eq 'Active')){ $id = $active_session.ID } } Start-Process -FilePath "mstsc" -ArgumentList "/v:$ps /shadow:$id /control /noconsentprompt" -Credential $Cred -Wait -WindowStyle Maximized
}else { $FormLabel4.Text = "КОМПЬЮТЕР НЕ ДОСТУПЕН!"
} }else { $FormLabel4.Text = "ЛОГИН ИЛИ ПАРОЛЬ НЕ ВЕРНЫЕ!"
} }else { $FormLabel4.Text = "ВЫ НЕ ВЫБРАЛИ КОМПЬЮТЕР!"
} }else { $FormLabel4.Text = "ВЫ НЕ ВВЕЛИ ПАРОЛЬ!"
} })
$FormButton2 = New-Object System.Windows.Forms.Button
$FormButton2.Location = New-Object System.Drawing.Size(10,440)
$FormButton2.Size = New-Object System.Drawing.Size(200,30)
$FormButton2.Text = "Закрыть"
$window_form.CancelButton = $FormButton3
$FormButton2.Add_Click({$window_form.Close();$window_form.Visible=$false})
$FormLabel4 = New-Object System.Windows.Forms.Label
$FormLabel4.Text = ""
$FormLabel4.Location = New-Object System.Drawing.Point(10,480)
$FormLabel4.AutoSize = $true
$window_form.Controls.Add($FormButton)
$window_form.Controls.Add($FormButton2)
$window_form.Controls.Add($ListBox)
$window_form.Controls.Add($FormTextBox1)
$window_form.Controls.Add($FormTextBox2)
$window_form.Controls.Add($FormLabel1)
$window_form.Controls.Add($FormLabel2)
$window_form.Controls.Add($FormLabel3)
$window_form.Controls.Add($FormLabel4)
$window_form.Add_Shown({$FormTextBox1.Select()})
$window_form.Topmost = $true
$window_form.MaximizeBox = $false
$result = $window_form.ShowDialog()

Powershell это очень хорошо, но запускать его жутко не удобно. Есть прекрасная возможность конвертировать полученный скрипт в exe файл