I'm trying to use Powershell to connect to VSO. Here is my code:
$tfsServer = New-Object System.Uri("the server is here")
$creds = [System.Net.CredentialCache]::DefaultNetworkCredentials
$tfsCollection = New-Object Microsoft.TeamFoundation.Client.TfsTeamProjectCollection($tfsServer,$creds)
$tfsCollection.Authenticate()
When it reaches the Authenticate line, it pops up a box for me to enter my credentials. I need it to not pop up this box, as this script will be scheduled, and I can't keep entering the credentials. How can I pass the current user's credentials to the TFS object?
Try this:
First, run this command which will prompt you once for your password, and then save it in an encrypted format.
read-host -prompt Password -assecurestring | convertfrom-securestring | out-file .\ps-password.pwd -ErrorAction Stop
Change the $username variable
$Username = 'jdoe'
$Password = Get-Content ".\ps-password.pwd" | ConvertTo-SecureString
$creds = New-Object -typename System.Management.Automation.PSCredential -ArgumentList $Username,$Password
$tfsServer = New-Object System.Uri("the server is here")
$tfsCollection = New-Object Microsoft.TeamFoundation.Client.TfsTeamProjectCollection($tfsServer,$creds)
$tfsCollection.Authenticate()
Use the constructor that just takes a URI. It will default to using the credentials of the current user.
To connect to Visual Studio Online, you have to follow the instructions at Buck's post. Shortly:
enable alternate credentials on the VSO account
set alternate user and password
use code similar to the following
$tfsServer = New-Object System.Uri("the server is here")
$netCred = New-Object NetworkCredential("alternate_user","alternate_password")
$basicCred = New-Object Microsoft.TeamFoundation.Client.BasicAuthCredential($netCred)
$tfsCred = New-Object Microsoft.TeamFoundation.Client.TfsClientCredentials($basicCred)
$tfsCred.AllowInteractive = $false
$tfsCollection = New-Object Microsoft.TeamFoundation.Client.TfsTeamProjectCollection($tfsServer,$tfsCred)
$tfsCollection.EnsureAuthenticated()
I know no way of using current process credentials with VSO, but you must explicitly pass them.
Use EnsureAuthenticated and do not specify credentials.
$tfsCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection("the server is here")
$tfsCollection.EnsureAuthenticated()
This way it will use the account running the process.
Related
I accidentally deleted 180 users from my AD and they aren't recoverable. I have recreated the accounts in AD and what not. This creates a new profile on their laptops when they login because of the new SID. I'm trying to write a script that grants them access to their old profile folder and create a shortcut on their desktop that leads there.
I've got the script working fine with one problem. The environment variables that are used, end up referring back to the admin account that runs the script. The users themselves don't have permission to change security on their old folder. I need to try and have the environment variables refer to the user yet have the privilege of an admin account to rewrite the permissions.
Here is the script so far.. I'm deploying this with Task Scheduler at the moment, which is another can of worms in that I'm not entirely understanding of the credential side of things there. I mean ideally, the task would run as a domain admin, execute the script asap, and have the script resolve the environment variables to the logged on user.
$permission = ":(OI)(CI)M"
$sam = $env:USERNAME
$folderName = "C:\Users\$($sam)"
Invoke-Expression -Command ( 'ICACLS $folderName /grant:r $sam$($permission) /t' )
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut("$Home\Desktop\Profile Backup.lnk")
$Shortcut.TargetPath = $folderName
$Shortcut.Save()
Its the $env:USERNAME and $home variables that are giving me trouble..
Or is there another way I should be tackling this problem?
You could use query session command to get the login name of the current logged on user. Then create NTAccount object based on that to retrieve SID and win32_userprofile WMI object to find out the profile path. Like this:
$m = query session | Select-String -Pattern "\>console\s*(\S*)\s"
$sam = $m.Matches[0].Groups[1].value
$acc = New-Object System.Security.Principal.NTAccount($sam)
$sid = $acc.Translate([System.Security.Principal.SecurityIdentifier]).Value
$profile = Get-CimInstance -ClassName win32_userprofile -Filter "SID='$sid'"
$folderName = $profile.LocalPath
Edit I have given it second thought over-night so I'll update the answer. You will be required to have domain admin password encrypted and then users will run the script.
It always sucks when something like this happens. I don't have a possibility to try this out, but I think the following approach would be feasible. The script asks user for password encrypts it and run the command as the user.
First phase would be to have a domain admin to encrypt his password to a file:
This is to be prepared by Domain Admin (distributed with the PS script) - I recommend changing password after the recovery is complete:
1) Read-Host -AsSecureString | ConvertFrom-SecureString | Out-File 'C:\<script_path>\admin_passwd.txt'
2) This is to be executed by user (you have to fill in the admin user id and have the password file distributed with the script). The script path can be obtained by (Get-Location).Path. I'm not adding it into the source code so you can decide how to implement it:
$permission = ":(OI)(CI)M"
$admin= "<your_admin_userid>"
$sam = $env:USERNAME
$domain = $env:UserDomain
$folderName = "C:\Users\$($sam)"
# get domain admin password
$encrypted_passwd = get-content 'C:\<script_path>\admin_passwd.txt' | ConvertTo-securestring
# Setting process invocation parameters.
$process_start_info = New-Object -TypeName System.Diagnostics.ProcessStartInfo
$process_start_info.CreateNoWindow = $true
$process_start_info.UseShellExecute = $false
$process_start_info.RedirectStandardOutput = $true
$process_start_info.RedirectStandardError = $true
$process_start_info.UserName = $admin
$process_start_info.Domain = $domain
$process_start_info.Password = $encrypted_passwd
$process_start_info.Verb = 'runas'
$process_start_info.FileName = 'ICACLS'
$process_start_info.Arguments = "$folderName /grant:r $sam$($permission) /t"
# Creating process object.
$process = New-Object -TypeName System.Diagnostics.Process
$process.StartInfo = $process_start_info
# Start the process
[Void]$process.Start()
$process.WaitForExit()
# synchronous output - captures everything
$output = $process.StandardOutput.ReadToEnd()
$output += $process.StandardError.ReadToEnd()
Write-Output $output
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut("$Home\Desktop\Profile Backup.lnk")
$Shortcut.TargetPath = $folderName
$Shortcut.Save()
How can I connect to an Azure SQLDatabase (Paas Instance) using Powershell without a username & password but rather with Active Directory. I can connect with a username and password when I use invoke-sqlcmd as below
$Servername = "XXXXXX.database.windows.net"
$params = #{
Database = $databasename
ServerInstance = $ServerName
Username = $UserName
Password = $password
'OutputSqlErrors' = $true
Query = $QueryString
}
Invoke-Sqlcmd #params
I need the ability to do it with Active Directory. I have read a few articles on how to connect with active directory as long as you specify it on the connection string (Context of C#) Using ODBC connection or other data sources. Since Powershell is based on .Net; this should be do-able..
$ConnString = "DRIVER=ODBC Driver 13 for SQL Server;SERVER=xxxxx.database.windows.net;DATABASE=DBName;Trusted_Connection=Yes"
$Conn = new-object System.Data.Odbc.OdbcConnection($ConnString)
$conn.open()
$cmd = new-object System.Data.Odbc.OdbcCommand("select getdate() as X", $Conn)
$data = new-object System.Data.Odbc.OdbcDataAdapter($cmd)
$dt = new-object System.Data.DataColumn
$data.Fill($dt)
$Conn.Close()
#`server=Server;database=Database;Authentication=ActiveDirectoryIntegrated;`
The objective of trying to use Active Directory is that, within Paas, only AD Accounts can Add other AD accounts. I want to be able to add other accounts with method rather than logging in the Azure portal and adding an AD account manually.
You could use Azure AD account to login Azure SQL database(Paas) by using Azure Active Directory Authentication. More information please refer to this link.
Note: Local domian AD user does not support this.
You could use following script to login with Azure AD authentication.
#You admin Azure AD user name
$Username = "shuitest#*****.onmicrosoft.com"
$Password = "********"
$Database = "testg"
$Server = 'test.database.windows.net'
$Port = 1433
$cxnString = "Server=tcp:$Server,$Port;Database=$Database;Authentication=Active Directory Password;UID=$UserName;PWD=$Password;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;"
$query = "select count(*) from dbo.Authors"
$cxn = New-Object System.Data.SqlClient.SqlConnection($cxnString)
$cxn.Open()
$cmd = New-Object System.Data.SqlClient.SqlCommand($query, $cxn)
$cmd.CommandTimeout = 120
$cmd.ExecuteNonQuery()
$cxn.Close()
The following sample shows how to invoke Add-AzureAccount without the popup dialog:
$username = "someorgid#orgaccount.com"
$password = "Pa$$w0rd" | ConvertTo-SecureString -AsPlainText -Force
$credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $password
Add-AzureAccount -Credential $credential
AAD does not / can not parse Kerbs tokens. In order to get integrated auth to work from your desktop, you need to have ADFS (or similar) in your environment. That way your desktop will authenticate against AAD, redirect to ADFS, and your kerbs token will be recognized.
See https://learn.microsoft.com/en-us/azure/sql-database/sql-database-aad-authentication for more information.
this now works for me in the connection string instead of user and pass
Authentication=Active Directory Integrated;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;
Depending on your query you might have to use $cmd.ExecuteScalar() instead of $cmd.ExecuteNonQuery() for example
$query = 'select ##version'
$cxn = New-Object System.Data.SqlClient.SqlConnection($cxnString)
$cxn.Open()
$cmd = New-Object System.Data.SqlClient.SqlCommand($query, $cxn)
$cmd.CommandTimeout = 120
$cmd.ExecuteScalar()
$cxn.Close()
I'm trying to automate a process of activating accounts by logging in to email, I have it working when I am not on the business network with the following code.
$username = "user"
$password = "pass"
$url = "url"
$ie = New-Object -com InternetExplorer.Application
$ie.visible=$true
$ie.navigate($url)
while ($ie.Busy -eq $true){Start-Sleep -seconds 1;}
$usernamefield = $ie.Document.getElementByID('UsernameTextBox')
$usernamefield.value = $username
$passwordfield = $ie.Document.getElementByID('PasswordTextBox')
$passwordfield.value = $password
$ie.document.getElementById("ctl00_ContentPlaceHolder1_SubmitButton").click()`
My issue is that once connected to the business network it then uses SSO to log in so I do not get the option to put in a username and password. To be able to put in a username and password I need to start IE in private mode. I have been able to start IE in private with the start-process command but I cannot find a way to select the window to type in the username and password.
Is there a way I can use powershell to log in to the website in a private browser?
You can get a handle to the private IE by starting it with start-process, as you referred to.
Start-Process -FilePath "C:\Program Files (x86)\Internet Explorer\iexplore.exe" -ArgumentList ' -private http://bogus.bogus'
Then you can connect to it by finding it -
$Shell = New-Object -Com Shell.Application
$apps = $shell.windows()
$ie = $apps | where { $_.locationname -eq 'http://bogus.bogus/' }
Happy scripting. :)
Does anyone know how to use password in System.DirectoryServices.ActiveDirectory context. Password is stored in a file.
$UserName="DomainName.com\JohnP"
$PassFile="C:\Temp\Pass.PPP"
$password = get-content $PassFile | ConvertTo-SecureString -AsPlainText -Force
$creds = new-object -typename System.Management.Automation.PSCredential("$UserName",$password)
$a = new-object System.DirectoryServices.ActiveDirectory.DirectoryContext("Forest", "MyForest.com",$UserName,$Password)
It always returns "Server rejected the credentials". If I store password in $Password variable, it works. For example, below code works:
$UserName="DomainName.com\JohnP"
$PassFile="C:\Temp\Pass.PPP"
$password = "MyPassword"
$creds = new-object -typename System.Management.Automation.PSCredential("$UserName",$password)
$a = System.DirectoryServices.ActiveDirectory.DirectoryContext("Forest", "MyForest.com",$UserName,$Password)
Can someone please help as to how to use password from a file and then use with System.DirectoryServices.ActiveDirectory context.
Many thanks!
Nratwa
A [PSCredential] stores the password as a secure string, so it's encrypted.
To get the unencrypted password value:
$creds.GetNetworkCredential().Password
I'm having a lot of difficulty with a PowerShell script that I'm trying to call a DirectoryServices query from. Currently, if I do a
$password = read-host "Password" -asSecureString
and subsequently
$credential = New-Object System.Management.Automation.PSCredential $username,$password
everything works fine. However if I try to pass the string parameter with a param($password) and then convert it to a secure string with this code:
$password = ConvertTo-SecureString -AsPlainText -Force $password
After extensive debugging I can see this is working fine in terms of converting the string to a securestring, but I get a bad user/password from DirectoryServices when I use the parameter. Everything works fine when read from the console. Any ideas on what I can do to accept a parameter OR take console input in the absence of a parameter?
This is what I was hoping would work, but doesn't:
if($password -eq $null) {
$password = read-host "Password" -asSecureString
} else {
$password = ConvertTo-SecureString -AsPlainText -Force $password
}
$credential = New-Object System.Management.Automation.PSCredential $username,$password
I recently created a script and was running into the same issue. The work around I found in my case was the following:
#Prompts for the username/password, enter the username in the form of DomainName\UserName
$Credential = get-credential
#Converts the password to clear text to pass it through correctly as passing through a secure string does not work.
$Password = $credential.GetNetworkCredential().password
#Converts the $Credential to just the DomainName/UsernName.
$Account = $credential.UserName
Hopefully this will work in your situation