I am trying to use credentials from some UI prompted to add Windows credentials using cmdkey:
$sessionCredential = $host.ui.PromptForCredential("Need credentials", "Please enter your user name and password.", "", "Server Crdentials")
$ps = ConvertFrom-SecureString -SecureString $sessionCredential.password
cmdkey.exe /add:server1 /user:$($sessionCredential.UserName) /pass:$($ps)
The credentials are added correctly, but the password is not.
What can I do?
Use the CredentialManager PowerShell module. It saves the password in the same place as cmdkey, but it can take PSCredential objects directly without needing to convert to text.
Import-Module CredentialManager
# Get the credential from the user with a windows credentials prompt:
$SessionCredential = Get-Credential -Message 'Please enter your server credentials'
# Save the credential object directly without unwrapping it:
New-StoredCredential -Credentials $SessionCredential -Target ServerCredentials -Persist Enterprise `
-Comment "Server Credentials for $($SessionCredential.UserName)" > $null
# Open the credential later
$SavedCred = Get-StoredCredential -Target ServerCredentials
# Delete if needed
Remove-StoredCredential -Target ServerCredentials
cmdkey /pass:$($ps) is prone to errors due to PowerShell garbling password characters.
Apparently, the problem is ConvertFrom-SecureString is returning an encrypted standard string, ConvertFrom-SecureString.
And the option to get plain text is not available on PowerShell 5.1.
I found the correct convert here.
I understand it is not secured. It is used inside secured clients.
See fixed code below:
$sessionCredential = $host.ui.PromptForCredential("Need credentials", "Please enter your user name and password.", "", "Server Crdentials")
$mpass = [System.Net.NetworkCredential]::new("",$sessionCredential.password).Password
cmdkey.exe /add:server1 /user:$($sessionCredential.UserName) /pass:$($mpass)
Cpt.Whale's answer worked like a charm. The only caveat was the need to copy/distribute the CredentialManager module before using it.
Related
I need to download a 51gb zip file from the internet, to open the website you need to enter a password.
I want to do this with a function in PowerShell(PSVersion:5.1.18362.752), but I can't get any further. My function looks like this:
$securepassword = "thepassword"
function Get-Files {
$Properties = #{
URI = "https://theurl"
Credential = $securepassword
}
Invoke-WebRequest #Properties -OutFile "C:\Users\$env:USERNAME\Desktop\thefiles.zip"
}
Can the parameter Credential only be used for Windows Credential?
Many thanks for the help
I think you are using Credentials wrong. Credentials is not password only. It is username plus password, and they should be instance of ICredentials
Please note, that credentials can be passed this way ONLY for web pages that request HTTP 401 authentication. If web page uses form-based authentication, you should process it as non-standard case and credentials will not work, you will need to post data, keep cookies, etc.
$localPath = [System.IO.Path]::Combine(
[System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::DesktopDirectory),
'OutFileName.zip')
$wc = [System.Net.WebClient]::new()
$wc.Credentials = [System.Net.NetworkCredential]::new($username, $plainTextPassword)
$wc.DownloadFile($uri, $localPath)
$wc.Dispose()
In windows 8.1 English OS/64-bit PC logged on with Microsoft Account
When i execute the above command the User name format will be as follows
//
In windows 8.1 Japanese OS/64-bit PC logged on with Microsoft Account
When i execute the above command the User name format will be as follows
/
Note:
System Name: lenovo-PC
DomainName: LENOVO-PC
UserName: TestAccount
Why it is returning different format in the different environment PC?
My logic is failing to get the token for the current logged in User.
Please help anyone.
There are many ways to get the username. Here are some examples:
(get-wmiobject Win32_ComputerSystem).username
or
[Environment]::UserName
or
whoami
or
[System.Security.Principal.WindowsIdentity]::GetCurrent().Name
For your specific problem, try this:
$domain = $env:UserDomain
$user = $env:UserName
$username = "$domain\$user"
I have a beginner's knowledge in scripting and programming and have a set of PowerShell commands that I am having issues with figuring out how to turn it into a script.
I can successfully run the following remote commands from my Windows 7 machine by running the Exchange 2007 PowerShell console as my domain administrator account and then running the following commands to pass the commands to the Exchange 2013 hybrid server for use with Office 365:
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://hybridexch2013.contoso.com/PowerShell/ -Authentication Kerberos
Import-PSSession $Session
Enable-RemoteMailbox jame.doe#contoso.com -RemoteRoutingAddress jane.doe#contosoinc.mail.onmicrosoft.com
The more I look into this I don't know that I am making progress. See below for how my logic is working in my head on this. I understand this is incorrect and incomplete. I have commented out a function I had earlier but wasn't sure if I was doing it correct or if it was needed at all.
param($enableMailbox)
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://hybridexch2013.contoso.com/PowerShell/ -Authentication Kerberos
Import-PSSession $Session -AllowClobber
$fname = Read-Host "What is the user's first name?"
$lname = Read-Host "What is the user's last name?"
#function Func($enableMailbox)
#{
$enableMailbox = "Enable-RemoteMailbox $fname.$lname#contoso.com -RemoteRoutingAddress $fname.$lname#contosoinc.mail.onmicrosoft.com"
#}
#Func $enableMailbox
Write-Host $enableMailbox
I also find that if I manually run:
Enable-RemoteMailbox $fname.$lname#contoso.com -RemoteRoutingAddress $fname.$lname#contosoinc.mail.onmicrosoft.com
I get nothing. So I am not even understanding how you pass variables to the string to run the command correctly. Even if I run:
$fname = "Jane"
$lname = "Doe"
$enableMailbox = "Enable-RemoteMailbox $fname.$lname#contoso.com -RemoteRoutingAddress $fname.$lname#contosoinc.mail.onmicrosoft.com"
Write-Host $enableMailbox
I get no results.
I was trying to understand the param function using help from these pages: Powershell script with params *and* functions
Passing a variable to a powershell script via command line
https://devcentral.f5.com/blogs/us/powershell-abcs-p-is-for-parameters
http://www.experts-exchange.com/Programming/Languages/Scripting/Powershell/Q_27900846.html
But I am finding the param function difficult to understand and not sure I am even going in the right direction here. So far the only thing that seems to work is connecting to the PowerShell remotely.
Please help if I am am to be helped with this one and lack of my abilities here.
Param Function in short...
Function Write-Something
{
Param($InputText)
Write-Host $InputText
}
Write-Something Hello
Result is: Hello
Use Param Section to add Parameters to your Function like in the example above,
So for your Script:
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://hybridexch2013.contoso.com/PowerShell/ -Authentication Kerberos
Import-PSSession $Session -AllowClobber
Function Enable-MBX
{
Param($Fname,$Lname)
Enable-RemoteMailbox "$Fname $Lname" -RemoteRoutingAddress "$fname.$lname#contoso.mail.onmicrosoft.com"
}
Enable-MBX Jane Doe
I think you're just confused about Write-Host.
I'm not certain if you're trying to write the enable-remotemailbox to console or execute it. The code you have should work fine for writing to console (screen) but won't execute the command. To execute the command:
Enable-RemoteMailbox "$fname.$lname#contoso.com" -RemoteRoutingAddress "$fname.$lname#contosoinc.mail.onmicrosoft.com"
Anything inside of double-quotes will expand. Ex: "$fname" will expand to "Bob" if $fname is equal to "Bob". If you encapsulate the whole command in quotes in a variable though, the Write-Host will NOT execute the command. Write-Host is designed to write output to the screen so you'll just see the command in the console.
If you want to further expand, you can use the sub-string operator $(). Ex:
Write-Host "$($fname.length).$($lname.length)"
Comes back as "3.5" for "Bob" and "Smith".
To avoid expansion, use single quotes:
Write-Host '$($fname.length).$($lname.length)'
Writes "$($fname.length).$($lname.length)" to the console.
The following (similar to your code) without quotes: Write-Host $fname.$lname#contoso.com will try to pull the $lname#contoso.com Property of $fname which in this context doesn't make sense (doesn't exist). To elaborate, it would be equivalent to Write-Host $fname.($lname#contoso.com).
I want to add Mozilla's root certs to Windows 7 without admin privileges.
Is there a straight forward way to add the root certificates into the current user's certificate store? I'd prefer to use Windows' native tools, without relying on something I'd have to download.
Some resources that looked promising.
Pre-converted PEM files by CURL - The Mozilla root certs converted to PEM and hosted by cURL. Here's a direct link to the PEM Encoded root certs
Verified HTTPs in Ruby - A general overview of how to obtain the root certificates.
How to get root certs for cURL - explains how to generate the PEM file from the Mozilla certificates yourself.
How to Import Certificates using Powershell - a ranting overview of how to install certificates that seems more complex than it ought to be.
I ended making a powershell script to do it.
VERIFY THIS CODE BEFORE RUNNING IT. It's adding all of the certificate authorities from http://curl.haxx.se/ca/cacert.pem to the current user's TRUSTED ROOT certificate store.
To run it in a single command, paste the following into a command prompt:
#powershell -NoProfile -ExecutionPolicy unrestricted -Command "iex ((new-object net.webclient).DownloadString('https://raw.github.com/jschaf/install-mozilla-certs/master/install-mozilla-cert.ps1'))"
Here's the Github link: https://github.com/jschaf/install-mozilla-certs
And the source:
# Variables
$url = "http://curl.haxx.se/ca/cacert.pem"
# Download the certificates
Write-Host "Downloading Mozilla certificates from $url."
$downloader = New-Object System.Net.WebClient
$rawcerts = $downloader.DownloadString("http://curl.haxx.se/ca/cacert.pem")
# Remove headers and begin/end delimiters and convert into a byte
# stream
$header = "-----BEGIN CERTIFICATE-----`n"
$footer = "`n-----END CERTIFICATE-----"
$match_string = "(?s)$header(.*?)$footer"
$certs_matches = Select-String $match_string -input $rawcerts -AllMatches
$certs_base64 = $certs_matches.matches | %{ $_.Groups[1].Value }
$certs_bytes = $certs_base64 | %{ ,[System.Text.Encoding]::UTF8.GetBytes($_) }
# Install the certificates
$user_root_cert_store = Get-Item Cert:\CurrentUser\Root
$user_root_cert_store.Open("ReadWrite")
foreach ($c in $certs_bytes) {
$cert = new-object System.Security.Cryptography.X509Certificates.X509Certificate2(,$c)
$user_root_cert_store.Add($cert)
}
$user_root_cert_store.Close()
Write-Host "Finished installing all certificates."
One annoying thing is that Windows will prompt for yes/no for every certificate. Since it's installing 158 certificates this gets old quick. If anyone knows how to prevent confirmation let me know or drop a pull request.
I'm logged in with my Windows 7 to the domain.
I want to programmaticaly change my user's password.
I tried to do "net user /domain" But i've got Access denied error.
I don't want to change it manually (CTRL+ALT+DELETE, change password ...).
I'll be happy to get an answer in command line, python, c++ or c#.
Thanks,
Mattan
Not sure how to include it in C#, but there is Netapi32.dll library that incorporates the NetUserChangePassword function. http://msdn.microsoft.com/en-us/library/windows/desktop/aa370650%28v=vs.85%29.aspx
In python, there are two easy ways to do it. With ctypes you can include it by typing:
from ctypes.wintypes import windll
ChangePassword = windll.Netapi32.NetUserChangePassword
Then change the password by typing:
ChangePassword(domainname, username, oldpass, newpass)
"domainname" could be zero if you want to assign the password on current logon domain.
However, if you already have windows tools for python istalled, then you could use win32net to change the password:
import win32net
win32net.NetUserChangePassword(domainname, username, oldpass, newpass)
Again, 0 can be used instead of domain name.
You can use the simple VB script (named changepass.vbs):
Dim UserDomain
Dim UserName
Dim NewPassword
UserDomain = WScript.Arguments.Item(0)
UserName = WScript.Arguments.Item(1)
NewPassword = WScript.Arguments.Item(2)
Set User = GetObject("WinNT://"& UserDomain &"/"& UserName & "")
Call User.SetPassword(NewPassword)
If err.number = 0 Then
Wscript.Echo "The password change was successful."
Else
Wscript.Echo "The password change failed!"
End if
It accepts 3 parameters: domain name, user name and a new password. The current user must have permissions to change the password. If you want to change password on the local computer provide "." as a domain name. Example:
cscript changepass.vbs "YOUR_DOMAIN" "user1" "qw23442q"