Power shell — это веселье

This feature will be available in PowerShell Universal 2.3.

“Windows PowerShell® Web Access, first introduced in Windows Server® 2012, acts as a Windows PowerShell gateway, providing a web-based Windows PowerShell console that is targeted at a remote computer. It enables IT Pros to run Windows PowerShell commands and scripts from a Windows PowerShell console in a web browser, with no Windows PowerShell, remote management software, or browser plug-in installation necessary on the client device. All that is required to run the web-based Windows PowerShell console is a properly-configured Windows PowerShell Web Access gateway, and a client device browser that supports JavaScript® and accepts cookies”

enter image description here

Newbie with coding, but doing my best, I believe I’m close.

I’m able to successfully log into the server via plink and powershell, but I’m having issues passing further commands after the initial server login. Command 1 requires a password to be entered after before I can actually pass command 3 and 4.

I have attempted send keys method here to at least press the enter key in the terminal, but neither have worked for me.

$wshell = New-Object -ComObject wscript.shell;
$wshell.AppActivate('windows powershell.exe')
Sleep 1
$wshell.SendKeys('~')
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.SendKeys]::SendWait('~');
 # Import the encrypted password from file $securePassword = Import-Clixml -Path "C:\Users\SecurePass.xml" # Import the encrypted username from file $secureUsername = Import-Clixml -Path "C:\Users\SecureUsername.xml" # Convert the secure password to plaintext $password = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($securePassword)) $username = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureusername)) $command1 = "mysql -u -p" $command2 = $password $command3 = "something goes here" $command4 = "something goes here" $servername = '8.8.8.8' $plinkpath = 'C:\Program Files\PuTTY\' #Execute SSH command &($plinkpath + "plink.exe") -v -batch $username@$servername -pw $password "$command1;$command2;$command3"
`-v` output
> Access granted
> Opening main session channel
> Opened main channel
> Allocated pty
> Started a shell/command
> Welcome to Pop!_OS 19.10 Last login: Thu Feb 1 12:09:32 2024 from myipaddress

Login failed for user error when connecting to MSQL server on Windows

When connecting to MSSQL server, we often see below error:

Login failed for user (Framework Microsoft SqlClient Data Provider)

 at Microsoft.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at Microsoft.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at Microsoft.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)

Creating a domain user login with SQL Server administration rights

# Import the SQL Server module
Import-Module SqlServer
# Define variables
$serverInstance = "POL-7CC5CS3" # Your SQL Server instance name
$domainUser = "UmbraCare\pbach" # The domain user you want to create a login for
# Connect to the SQL Server instance
$sqlServer = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Server -ArgumentList $serverInstance
# Create a new login object for the domain user
$newLogin = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Login -ArgumentList $sqlServer, $domainUser
# Set the login properties for a Windows-authenticated user
$newLogin.LoginType = [Microsoft.SqlServer.Management.Smo.LoginType]::WindowsUser
# Create the login on the SQL Server instance
$newLogin.Create()
# Add the login to the sysadmin server role
$sysadminRole = $sqlServer.Roles["sysadmin"]
$sysadminRole.AddMember($domainUser)
# Output the result
Write-Output "Login for $domainUser created and added to sysadmin role successfully on $serverInstance."

This script contains two important lines:

  • After creating the Windows-authenticated login, it retrieves the sysadmin server role using $sqlServer.Roles[“sysadmin”].
  • It then adds the newly created login to the sysadmin role using $sysadminRole.AddMember($domainUser).
  • This script grants the highest level of permissions available in SQL Server to the specified domain user. Ensure that this is in line with your organization’s security policies.
  • The domain user you specify must already exist in Active Directory.
  • Running this script requires that you have sufficient permissions on the SQL Server instance to create logins and modify server roles.
  • Always review the implications of granting sysadmin privileges, as users with this role can perform any action on the SQL Server instance.

Installing the missing SqlServer module via Powershell

During script execution, you can encounter a common error:

Import-Module : The specified module ‘SqlServer’ was not loaded because no valid module file was found in any module di
rectory.

The error message you’re seeing indicates that the SqlServer PowerShell module is not installed on your system, or PowerShell can’t find it in the default module directories.

To resolve this, you need to install the SqlServer module from the PowerShell Gallery.

This module provides the cmdlets necessary to interact with SQL Server, including creating logins and assigning roles.

Here’s how you can install the SqlServer module:

Install-Module -Name SqlServer -AllowClobber -Scope CurrentUser

:/>  ✅ Как правильно установить Windows 10 на компьютер с уже установленной Windows XP -

The -AllowClobber parameter is optional and allows the cmdlet to overwrite any conflicting commands in other modules.

Step 3: Verify Installation: After installation, you can verify that the module is installed by using the Get-Module -ListAvailable SqlServer command. This command lists all installed modules that match the name “SqlServer.”

checking avaliable SqlServer modules via Powershell

Step 4: Retry the Script: With the SqlServer module installed, try running your script again. PowerShell should now be able to recognize and use the cmdlets provided by the module.

If you encounter any errors during the installation, make sure that your version of PowerShell supports the PowerShellGet module and that your system is connected to the internet.

If you’re using an older version of PowerShell, you might need to update it or install the PowerShellGet module manually.

Final thoughts

🌐 Explore More: Interested in learning about .NET and web development insights?

Explore our blog for a wealth of information and expert advice.

Key Takeaways

  • Customizing Windows login messages enhances security and user experience.
  • The provided PowerShell script offers a swift method to update login titles and messages.
  • Admin privileges are required due to changes in the system registry.
  • The script is compatible with Windows 10 and Windows Server 2016 onwards.
  • While Group Policy Objects can perform similar tasks, this script provides quicker, more agile adjustments.
  • Misuse, like sharing sensitive information via login messages, can pose security threats.
  • Always test the script in a sandboxed environment before wide deployment.
  • Platforms like NinjaOne further facilitate management and deployment of such scripts across large networks.

Background

The Script

#Requires -Version 5.1
<#
.SYNOPSIS Changes the logon title and message.
.DESCRIPTION Changes the logon title and message.
.EXAMPLE -Title "My Title" -Message "My Logon Message" Set the title and message.
.EXAMPLE PS C:> Set-LogonMessage.ps1 -Title "My Title" -Message "My Logon Message" Set the title and message.
.OUTPUTS None
.NOTES Minimum OS Architecture Supported: Windows 10, Windows Server 2016 Release Notes: Renamed script and added Script Variable support, updated Set-ItemProp
By using this script, you indicate your acceptance of the following legal terms as well as our Terms of Use at https://www.ninjaone.com/terms-of-use. Ownership Rights: NinjaOne owns and will continue to own all right, title, and interest in and to the script (including the copyright). NinjaOne is giving you a limited license to use the script in accordance with these legal terms. Use Limitation: You may only use the script for your legitimate personal or internal business purposes, and you may not share the script with another party. Republication Prohibition: Under no circumstances are you permitted to re-publish the script in any script library or website belonging to or under the control of any other software provider. Warranty Disclaimer: The script is provided “as is” and “as available”, without warranty of any kind. NinjaOne makes no promise or guarantee that the script will be free from defects or that it will meet your specific needs or expectations. Assumption of Risk: Your use of the script is at your own risk. You acknowledge that there are certain inherent risks in using the script, and you understand and assume each of those risks. Waiver and Release: You will not hold NinjaOne responsible for any adverse or unintended consequences resulting from your use of the script, and you waive any legal or equitable rights or remedies you may have against NinjaOne relating to your use of the script. EULA: If you are a NinjaOne customer, your use of the script is subject to the End User License Agreement applicable to you (EULA).
.COMPONENT OSSecurity
#>
[CmdletBinding()]
param ( [Parameter()] [String]$Title, [Parameter()] [String]$Message
)
begin { if ($env:title -and $env:title -notlike "null") { $Title = $env:title } if ($env:message -and $env:message -notlike "null") { $Message = $env:Message } function Test-IsElevated { $id = [System.Security.Principal.WindowsIdentity]::GetCurrent() $p = New-Object System.Security.Principal.WindowsPrincipal($id) if ($p.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)) { Write-Output $true } else { Write-Output $false } } function Set-ItemProp { param ( $Path, $Name, $Value, [ValidateSet("DWord", "QWord", "String", "ExpandedString", "Binary", "MultiString", "Unknown")] $PropertyType = "DWord" ) # Do not output errors and continue $ErrorActionPreference = [System.Management.Automation.ActionPreference]::SilentlyContinue if (-not $(Test-Path -Path $Path)) { # Check if path does not exist and create the path New-Item -Path $Path -Force | Out-Null } if ((Get-ItemProperty -Path $Path -Name $Name)) { # Update property and print out what it was changed from and changed to $CurrentValue = Get-ItemProperty -Path $Path -Name $Name try { Set-ItemProperty -Path $Path -Name $Name -Value $Value -Force -Confirm:$false -ErrorAction Stop | Out-Null } catch { Write-Error $_ } Write-Host "$Path$Name changed from $CurrentValue to $(Get-ItemProperty -Path $Path -Name $Name)" } else { # Create property with value try { New-ItemProperty -Path $Path -Name $Name -Value $Value -PropertyType $PropertyType -Force -Confirm:$false -ErrorAction Stop | Out-Null } catch { Write-Error $_ } Write-Host "Set $Path$Name to $(Get-ItemProperty -Path $Path -Name $Name)" } $ErrorActionPreference = [System.Management.Automation.ActionPreference]::Continue }
}
process { if (-not (Test-IsElevated)) { Write-Error -Message "Access Denied. Please run with Administrator privileges." exit 1 } try { Set-ItemProp -Path "HKLM:SOFTWAREMicrosoftWindowsCurrentVersionPoliciesSystem" -Name "legalnoticecaption" -Value $Title -PropertyType String Set-ItemProp -Path "HKLM:SOFTWAREMicrosoftWindowsCurrentVersionPoliciesSystem" -Name "legalnoticetext" -Value $Message -PropertyType String } catch { Write-Error $_ exit 1 }
}
end {
}

Access 300+ scripts in the NinjaOne Dojo

:/>  Использование DxDiag | World of Tanks Blitz

Detailed Breakdown

Let’s delve into the mechanics of the script:

  • Cmdlet Binding and Parameters: The script is designed as a PowerShell function using the CmdletBinding attribute. This means the script can be used as a reusable function and can accept parameters, specifically the title and message for the login prompt.
  • Administrator Check: Two embedded functions are utilized, Test-IsElevated and Set-ItemProp. The former checks if the script is run with administrator privileges, vital since modifying registry keys (which the script does) requires elevated permissions.
  • Registry Modifications: The Set-ItemProp function either modifies existing registry values or creates new ones. The script targets two primary keys, legalnoticecaption (for the title) and legalnoticetext (for the message), which govern the login message on Windows.

Potential Use Cases

Comparisons

While Group Policy Objects (GPO) can also be used to set login messages, this script offers a more agile approach. GPOs might take time to propagate and may not be suitable for rapid changes. The PowerShell script, on the other hand, can be swiftly executed on a machine-by-machine basis or deployed widely via a system management tool.

FAQs

  • Can this script be run on any Windows machine? 
    It’s designed for Windows 10 and Windows Server 2016 and above. Earlier versions may not support the involved cmdlets.
  • Is it necessary to run the script with administrative rights? 
    Yes, since it modifies the system registry, elevated permissions are mandatory.

Implications

Recommendations

  • Ensure clarity and brevity in your login messages.
  • Test the script in a controlled environment before broad deployment.
  • Maintain regular backups of your system registry.

Final Thoughts

Login Page

Documentation on how to customize the login page.

Login page customization requires a license.

Remove Microsoft Azure Account

7

Select Particular Subscription

6

Run Microsoft Azure PowerShell as Administration.

1

Customizing the login page with an App

You can override the login page with an app by setting an app’s base URL to /login. You need to ensure that the app does not require authentication.

You will then need to implement the login features manually.

Implementing an app-based login page

 'Content-type': 'application/json; charset=UTF-8' .then((response) => response.json()). window.location.href = 'http://localhost:5000/app2'# Send Email Here with a link like: http://localhost:5000/app?email=email&passcode=$Password# For Testing  Set-UDClipboard -Data "http://localhost:5000/app/Home?email=$($EventData.email)&passcode=$Password" -ToastOnSuccess"Please check your email!""Send Login Email"

The resulting app will look like this when loaded.

A URL will be generated and, in this example, copied to the clipboard.

# Check the cache to see if this email + passcode combination is valid# Do standard form login here

How to use Windows PowerShell Web Access

Now that the Windows Feature is installed and the access is there, you can use your browser and connect to https://servername.domain.local/pswa. (In my example, https://w2k22dc.test.local/pswa) Note that it shows Windows Server 2016 even though my server is running Windows Server 2022 😉

Power shell — это веселье

You can now enter the credentials:

Power shell — это веселье

After clicking Sign In, you will see this:

Power shell — это веселье

In the lower right you can see the server that you are connected to. You can type command using the line at the buttom and clicking on Submit. I ran the Get-Service cmdlet and it shows all the services, for example:

:/>  WinSxs очистить от мусора (Installer, ServiceProfiles) на RDC
Power shell — это веселье

You can reconnect your session after inactivity, delete or start a new session:

Power shell — это веселье

But you can also Save your session and return to it by clicking on Save:

Power shell — это веселье

You can autocomplete commands using the Tab-key or the arrow pointing right works and you can browse the History by clicking the arrow pointing up or using the Up-Arrow. Keys that don’t work are: (Because you’re running it in a browser)

Power shell — это веселье

There’s a list of things that don’t work here, most important ones are:

  • Double-hop.   You can encounter the double-hop (or connecting to a second computer from the first connection) limitation if you try to create or work on a new session by using Windows PowerShell Web Access. Windows PowerShell Web Access uses a remote runspace, and currently, PowerShell.exe does not support establishing a remote connection to a second computer from a remote runspace. If you attempt to connect to a second remote computer from an existing connection by using the Enter-PSSession cmdlet, for example, you can get various errors, such as “Cannot get network resources.”
  • Windows PowerShell Web Access uses and has the same limitations as a remote Windows PowerShell session. Commands that directly call Windows console APIs, such as those for console-based editors or text-based menu programs, do not work because the commands do not read or write to standard input, output, and error pipes. Therefore, commands that launch an executable file, such as notepad.exe, or display a GUI, such as OpenGridView or ogv, do not work. Your experience is affected by this behavior; to you, it appears that Windows PowerShell Web Access is not responding to your command.
  • Persistent Windows PowerShell sessions (Reconnection).   After you time out of the Windows PowerShell Web Access gateway, the remote connection between the gateway and the target computer is closed. This stops any cmdlets or scripts that are currently in process. You are encouraged to use the Windows PowerShell -Job infrastructure when you are performing long-running tasks, so that you can start jobs, disconnect from the computer, reconnect later, and have jobs persist. Another benefit of using -Job cmdlets is that you can start them by using Windows PowerShell Web Access, sign out, and then reconnect later, either by running Windows PowerShell Web Access or another host (such as Windows PowerShell® Integrated Scripting Environment (ISE)).

Customizing the login page

Next, we can create a loginPage.ps1 file in the repository folder. Add the various colors, text and image URL to customize the login page. As soon as you save this file, you can refresh the login page to see the result.

'DBATools Web Portal'

This login page looks like this.

How to install

Windows Feature

You can install it from the Roles and Features GUI using Server Manager:

Power shell — это веселье

Or from a PowerShell command prompt:

Install-WindowsFeature –Name WindowsPowerShellWebAccess -IncludeManagementTools

At the end of the installation this link is shown:

For more information about how to finish installing and configuring Windows PowerShell Web Access, see http://go.microsoft.com/fwlink/?LinkID=221050.

Configuring the Gateway

To add the PSWA (PowerShellWebAccess) website to IIS, you must run to Install-PsaWebApplication cmdlet. You can run this with the -UseTestCertificate to let it create a certificate for you. This is ok for testing, but it’s better to have an official certificate. (My test Server is a Certificate Authority and I will be using a certificate from that).

In this example below I install the PSWA website on my test server:

PS C:\Users\Administrator> Install-PswaWebApplication
Creating application pool pswa_pool...
Name State Applications
---- ----- ------------
pswa_pool Started
Creating web application pswa...
Path : /pswa
ApplicationPool : pswa_pool
EnabledProtocols : http
PhysicalPath : C:\Windows\Web\PowerShellWebAccess\wwwroot

Restricing Access

Add-PswaAuthorizationRule –UserName Test\Administrator -ComputerName W2K22Member.test.local -ConfigurationName Microsoft.powerShell

After running the command, you should see this:

Power shell — это веселье

Enter Credentials

3

4

Get Subscription Details

5