I have successfully built a working simple program that displays a menu and allows a user to choose which script to open and it runs in the same window.
I would like to be able to store credentials so that you would only need to enter them once while using this program and it passes them through to other scripts.
Please can someone advise.
I played around and found a solution. Seems the variables are carried through the session regardless if it runs a new script.
This bit of code sorted it out.
if ($cred -eq $null)
{
try {
Write-Host "`r`n"
$cred = Get-Credential -Credential $username
}
catch {
Write-Host -ForegroundColor Red "`r`nSomething has gone wrong with entering credentials. Please try run the script again or if issues persist please contact the system administrator.`r`n"
Return-ExitRestart
}
Related
When I am running commands or installing software remotely using PowerShell - Invoke-Command etc I would like sometimes to be able to show a message on the remote screen so the user knows something is happening, or when work done etc.
I would like to if possible make this message look as professional as possible, e.g. better than just a standard winform message box if it can be done? perhaps more the style of the Windows 10 ones with coloured background and use of image if possible.
Spent a while googling but most seem to relate to using obsolete methods such as net-send or using msg.exe.
Thanks
https://michlstechblog.info/blog/powershell-show-a-messagebox/
So the issue really isnt creating the messagebox itself, its having it show on the users session.
So when you run a command against a system, youre using your creds to run the command therefore it wont show in the users session. You can get around this by running it in the users context using a task scheduler. I have a script that does all this for you but, id hate to recreate the wheel and will have to wait till monday (when im at work) to post it here.
It accepts user input in your sessions that outputs it to a vbs, which then copies it over the message to the users machine, and a task schedule is set to run immediately for the user thats logged in.
edit: The script is this without the task scheduler. I just invoke gwmi win32_computersystem | Select -ExpandProperty username to get the current user logged in and add it to the task.
#Prompt for messge
$strMSG = Read-Host -Prompt "Enter message"
#deleting vbs if it exists
del C:\brief\test.vbs
#creating vbs from scratch so it doesnt override
New-Item C:\brief\test.vbs
#Appending each the values to a seperate line
Add-Content C:\brief\test.vbs 'Set objShell = Wscript.CreateObject("WScript.Shell")'
Add-Content C:\brief\test.vbs "strText = `"$strMSG`""
Add-Content C:\brief\test.vbs 'intButton = objShell.Popup(strText,0,"Computer Support",48)'
#calling on the script
& cscript C:\brief\test.vbs
Found a great solution here which appears on quick testing to work well for displaying a toast notification on a remote machine
https://smsagent.blog/2019/06/11/just-for-fun-send-a-remote-toast-notification/
Complete Powershell Noobie here.
I have a .bat file that I would like to convert to Powershell.
Basically when run; it asks the user to enter their Active Directory credentials. Once validated; it starts a RSAT tool (example: dhcpmgmt.msc) as the elevated domain user.
However, if credentials are incorrect (if %ERRORLEVEL% EQU 5); it does a GOTO an echo "Incorrect username and password" and then loops back requesting the user to enter their credentials again.
When I use:
do
{
Start-Process -FilePath C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -Credential (Get-Credential "$env:USERDNSDOMAIN\") -ArgumentList "C:\Windows\System32\dhcpmgmt.msc"
} until ($response -eq $null)
It works. But if I enter an incorrect password; the window closes.
I would like a notification information the user that the Username/Password is incorrect and then re-direct them to enter their credentials again. This would loop until either the user enters the correct credentials or simple clicks the cancel button.
Any help/guidance is highly appreciated. Thanks a bunch in advance!
You can run this in the while loop to keep asking for credentials until they are valid.
Take credentials
Run powershell with new creds
If fails, ask for new credentials. Break out of the loop if no.
while ($true)
{
$userCreds = Get-Credential "$env:USERDNSDOMAIN\"
try {
Start-Process powershell -Credential $userCreds -ArgumentList "C:\Windows\System32\dhcpmgmt.msc" -ErrorAction Stop
break
}
catch {
Write-Output "Invalid Credentials"
Write-Output "Enter new credentials?"
if ((Read-Host) -ne "Yes") { break }
}
}
This should do the needful.
Loop to Get and Check Credential
Try-Catch Credential Check
Raise Messagebox on Failed Credential
Exit script on Cancel.
$Credential=$null
while ($Credential -eq $null) {
$Credential = Get-Credential -Username "$env:USERDNSDOMAIN\" -message "Enter Admin Password"
try {
Start-Process -FilePath cmd.exe /c -Credential $Credential
}
catch {
$Credential=$null
IF (
$([System.Windows.MessageBox]::Show('Invalid UN/PW! ?','Credential Error','OKCancel','Error')
) -eq "Cancel") { EXIT}
}
}
### Your code to launch RSAT tools here:
We use a while loop.
While the credentials are NULL we p, getting the credentials, storing it as a secure string in a variable, then do a try-catch on the test of running a process, if that will try to get the credentials again, and we store the credentials in a variable as a secure string.
Initially, credentials are NULL so we ask for them.
Then we use Try to test the credentials by initiating a process as them.
If that fails we Catchit and 1st set credentials to NULL again, then we Raise a Windows Message Box to the user letting them know the credentials failed and checking if they would like to try again (OK) or Cancel.
If they respond with Cancel, there is no point in continuing the script so we just exit.
Otherwise, we just go ahead with our loop as planned
I have a basic understanding of PowerShell.
I would like to get my hands on a PowerShell script that will run at logoff.
This script needs to warn a user that their USB storage device is still plugged in before they sign out and they have to acknowledge the fact that it is and then select ok and then proceed to sign out
I know that the script needs to placed in an accessible location with the correct permissions and that a GPO can be used to enforce this. The script part is what I need help with..
If anyone out there in the interwebs please help?
Environment OS: Windows 10
AD not in use. Novell system used.
After you checked out what Franco stated, you can try something like the following. But still need to figure out how to make it work properly:
$usbs = GET-WMIOBJECT win32_diskdrive | Where { $_.InterfaceType –eq ‘USB’ }
$devices = #()
foreach($usb in $usbs){
$devices += $usb.Model + ". "
}
$input = [System.Windows.MessageBox]::Show("There are USB devices connected, $($devices | Out-String) Would you like to proceed logging off?","Warning","YesNoCancel","Error")
if($input -eq "Yes"){
shutdown -L
}elseif($input -eq "No"){
shutdown -A
}else{
break
}
You will need to find a way to make the user input visible before the logoff screen.
I have the below PowerShell script (myscript.ps1) in which I ask for username and password. Depending on the username and password it copies a file to a certain destination.
$credentials = Get-Credential
if ($credentials.Username -eq "user1" -And $credentials.GetNetworkCredential().password -eq "pass1")
{ Copy-Item "test1.pdf" "\test\test1.pdf"; }
else
{ Copy-Item "test2.pdf" "\test\test2.pdf"; }
Requirement: I want to make this file protected so no one can edit it and see the username and password.
PS2EXE
I found a solution found here which converts the PowerShell script to an .exe file. When I originally run the script using PowerShell a dialog box appears allowing me to enter the username and password:
After the .exe is generated and when I run it the credentials dialog box no longer appears. Instead, the console appears saying "Credential:"
I don't know why? I want the credentials form to still appear when running the exe. Any thoughts please?
Q: Why does the EXE prompt with "Credential"?
This isn't an answer to the real question, and is based on guessing/supposition about PS2EXE, but I hope it is useful to clear up some confusion.
Having looked briefly at the PS2EXE page linked above, it seems that this utility encodes the script in Base64 and bundles it with a lightweight (?) custom PowerShell host. When run, I suppose the EXE starts the host, decodes the script and runs it.
The problem is that the Get-Credential cmdlet is running within a PS host that probably can't interact with the desktop. That is, it can't put up the GUI prompt for credentials. It therefore needs to prompt for the Credential property on the command line, explaining why you see that behaviour.
Workaround with Read-Host?
Instead of trying to use Get-Credential to prompt for username and password, you could embrace what PS2EXE seems to be doing and just use Read-Host:
$UserName = Read-Host "Enter username"
$Password = Read-Host "Enter password" -AsSecureString
$Credentials = New-Object System.Management.Automation.PSCredential $UserName,$Password
if ($credentials.Username -eq "user1" -And $credentials.GetNetworkCredential().password -eq "pass1")
{ ... }
Using -AsSecureString will hide the password on the screen. The $Password variable will be of type System.Security.SecureString, which can be used to create a PSCredential object as shown.
You'd need to test this, but it seems that you're able to read from the shell but not from a GUI prompt.
And just to be clear: none of this is anywhere near best-practice security. If you need authentication/authorization for these activities, step back and look at the problem again.
Workaround with two scripts?
It seems that PS2EXE doesn't support -AsSecureString in the same way that normal PowerShell does, i.e. it doesn't hide the characters. A possible workaround for this would be to collect the username and password from the user in one script and then pass them to a PS2EXE-converted script for processing.
Launch-MyScript.ps1:
$Credentials = Get-Credential
& MyScript.exe $Credentials.Username $Credentials.Password
MyScript.exe (coverted with PS2EXE):
param($Username,$Password)
$Credentials = New-Object System.Management.Automation.PSCredential $Username,$Password
if ($Credentials.Username -eq "user1" -and
$Credentials.GetNetworkCredential().password -eq "pass1")
{
...
}
The user runs Launch-MyScript.ps1 and completes the password prompt. Then the EXE is run automatically with the username and password passed in as arguments. Note that, as shown above, the password is a Secure String. Test this; I'm not using PS2EXE so it's a theoretical solution at the moment.
If you can't pass $Password along the pipeline as a Secure String object, you can convert it to text with ConvertFrom-SecureString in the first script, then conver it back with ConvertTo-SecureString in the second one.
According to this article http://windowsitpro.com/powershell/protect-your-powershell-scripts you should first set ur execution policy to AllSigned by Set-ExecutionPolicy AllSigned, then create a certificate using makecert cmdlet.
Then u can sign single script using Set-AuthenticodeSignature cmdlet or use .pfx File to Sign a Script which appears even safer.
Hope it helps a bit.
I am trying to run a script against exchange to bring back all of the mailboxes a certain user has access to. I want to be able to input the usersname using read-host. I currently have this:
$username = Read-Host("Please enter users username")
#Enable Exchange cmdlets
add-pssnapin *exchange* -erroraction SilentlyContinue
Get-MailBox | Get-MailboxPermission -User $username | FL > C:\MailboxPermissions.txt
However, when I run this via powershell, it asks for the username, looks like it is starting to run the script, then powershell just exits and there is not data outputted
Any help would be greatly appreciated
Thanks for all the help
I finally figured it out and there were a couple of issues. It was to do with the result size. I added -resultsize unlimited:
$username = Read-Host("Please enter users username")
add-pssnapin *exchange* -erroraction SilentlyContinue
>Get-MailBox -resultsize unlimited | Get-MailboxPermission -User $username | FL > C:\MailboxPermissions.txt
It would also not work by running the .ps1 file as this was not run by admin, and it needs admin permissions to output to the location I want. Once I created a shortcut for it to run via the powershell.exe with admin credentials it is now working as expected.
The problem is that you are only out putting to the screen.
This means that when you run your script it will carry out the required action, print to screen and close the window immidiatly. In turn, this means you can't see the output.
As #DarkLite1 mentioned, you could output to a file.
Or, you could simply allow the console to wait before closing. This is done like this at the end of your code:
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
You may also need a Write-Host on the last action in your code snippet, I'm not entirely sure as I am not familiar with how Get-Mailbox works, but try it without first.
To summarize, You must keep the window open or print the results to file to actually see anything. The code you have currently will complete so fast you will never see any output.