Powershell Special characters / Automating build - PSRemoting - powershell

I am using Teamcity and Powershell to automate few builds. Teamcity runs under lets say account A. There are few executable that needs to be run under account B. Account B has access to DB (windows auth integrated security access) and needs to go and create few tables on install. Passwords for account B is saved in the text file. I am having few issues with this.
1) Account B can have any special characters. I am reading XML file (as this file can be saved in a location where only Account A has access) and new up PSCredential to do the PSRemoting. I am using something like
$secpasswd = ConvertTo-SecureString $passwordFromXMLFile -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ("username", $secpasswd)
$PasswordFromXMLFile can have any special characters. How should I deal with this?
2) When I try to run the executable in context of account B (after I somehow escaped and connected using this account), I am seeing the executable runs under anonymous account instead of domainname\B account. Is there some setting that I need to make sure it runs under account B.
My code looks something like - this is not the exact code I am just extracting some relevant portion.
$secpasswd = ConvertTo-SecureString $passwordFromXMLFile -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ("B", $secpasswd)
$session = New-PSSession -ComputerName $serverName -Credential $mycreds
I see the session connects fine. to the computer
$scriptblock = {
Start-Process $exeName $arguments - wait
}
invoke-command -session $session -scriptblock $scriptblock
Thoughts? Start-Process runs but it executes on anonymous authority instead of account B.

Related

Connect-PnPOnline - A positional parameter cannot be found that accepts argument 'System.Management.Automation.PSCredential

I am trying to connect to a sharepoint site from a PowerShell job running in an Azure App Service, whenever i try to connect it gives me the following error:
Authentication failed: A positional parameter cannot be found that accepts argument 'System.Management.Automation.PSCredential'.
When looking in the source code for the method Connect-PnPOnline for the positional parameter -Credentials it expects a CredentialPipeBind, which is a class public sealed class CredentialPipeBind
The class looks like it's meant to switch between a credential from the windows credential manager, or a powershell credential object.
The Azure job may be wanting to get the literal type from the positional parameter?
I tried giving it a
Function Set-SpsConnection ($url, $creds) {
$crpb = [SharePointPnP.PowerShell.Commands.Base.PipeBinds.CredentialPipeBind]::new($creds)
Connect-PnPOnline –Url $sharepointurl –Credentials $crpb
}
But to no avail, now it thinks i'm using SharePointPnP.PowerShell.Commands.Base.PipeBinds.CredentialPipeBind instead of CredentialPipeBind, maybe I can somehow reference the assembly so that i don't have to specify?
The issue seems to only appear when it is ran by a job or i start the script in the Kudu Console with .\scriptname.ps1 , when I execute the code in the Kudu console Copy-Paste it seems to work fine...
In my opinion this just seems like an inherent flaw within the azure job system, that it will only interpret litteral types and not run the same as on a client.
According to my research, if you want to connect to a sharepoint site with Credentials in PowerShell, the parameter Credentials should be a PSCredential object or a string(the cert name credentials from the Windows Credential Manager). For more details, please refer to the article the issue and the document
For example
$name = "username"
$password = "password"
$secpasswd = ConvertTo-SecureString $password -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ($name, $secpasswd)
Connect-PnPOnline -Url https://hanxia.sharepoint.com/ -Credentials $mycreds
Get-PnPList
update
According to my test, we can run the script in Azure web job
Update the module to Azure vai kuduo
Create a web job. My script is as below
$ProgressPreference="SilentlyContinue"
Import-Module '<the path of your module>\SharePointPnPPowerShellOnline' -DisableNameChecking
$name = "username"
$password = "password"
$secpasswd = ConvertTo-SecureString $password -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ($name, $secpasswd)
Connect-PnPOnline -Url https://<>.sharepoint.com/ -Credentials $mycreds
Get-PnPList

How to copy a file from local work space to remote server (not a network shared path) with powershell

I am trying to copy a file from my local workspace to a remote server (not a network shared path) by using the powershell command through Inline Powershell" task in TFS vNext build definition.
FYI, destination path is not a network shared path
I tried with below commands
$Session = New-PSSession -ComputerName "remote server name" -Credential "domain\username"
Copy-Item "$(Build.SourcesDirectory)\Test.htm" -Destination "C:\inetpub\wwwroot\aspnet_client\" -ToSession $Session
But it's promoting for the password every time and I tried with entering the password manually and the result looks good.
How can we achieve this step without prompting password or credentials
Are you sure it's not on a network share? :)
Powershell only takes password as a secure string. You can use $credential = Get-Credential to render a really cool box to store those credentials for you, or if you want to store your login programmatically (not recommended for obvious security reasons) use this:
$passwd = ConvertTo-SecureString "<password>" -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential("<username>",$passwd)
There might be a way to inherit your current domain credentials, but that's way beyond me, and a quick google search turns up nothing.
EDIT: Sorry I forgot to post the whole thing:
$passwd = ConvertTo-SecureString "<password>" -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential("<username>",$passwd)
$Session = New-PSSession -ComputerName "remote server name" -Credential $credential
Copy-Item "$(Build.SourcesDirectory)\Test.htm" -Destination "C:\inetpub\wwwroot\aspnet_client\" -ToSession $Session

PowerShell Computer StartUp-Script - Switch user-context?

Through Microsoft Group Policy I did define to run a Powershell-Script on Computer Start-Up. Also I have the requirement to run a Powershell-Script as Scheduled Task without saving credentials.
On both scenarios I have the same problem ...
I want to run a Citrix Powershell-Command (PSSnapIn) like:
Set-BrokerMachine -MachineName "domain.local\$env:COMPUTERNAME" -AdminAddress "RemoteServer.domain.local" -InMaintenanceMode $True
Manual: https://citrix.github.io/delivery-controller-sdk/Broker/Set-BrokerMachine/
Of course only users who have the permission could run those Citrix-commands. I would be able to give a domain-user the permission to run the command "Set-BrokerMachine", but in the mentioned scenarios the PowerShell-scripts run in context of the system-user.
I did simulate the system-user by PSExec:
Error running as System-User
My scripts do other things of course and I want to keep them running as System-User, but now I am looking for a clean solution to get those Citrix-commands running.
If possible, I don't want to save credentials in my scripts.
EDIT #1:
I would be able to workaround with the following code:
$Username = "MySpecialUser"
$Password = 'MyPassword'
$SecurePassword = ConvertTo-SecureString $Password -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential $Username, $SecurePassword
$Result = Invoke-Command -Session ( New-PSSession -ComputerName "RemoteServer.domain.local" -Credential $Credential ) -ScriptBlock {
Add-PSSnapin Citrix*
Set-BrokerMachine -MachineName "domain.local\$args" -InMaintenanceMode $True
} -ArgumentList $env:COMPUTERNAME -HideComputerName
Remove-PSSession -InstanceId $Result.RunspaceId
I don't like this because:
The code has to contain credentials (ofc I could encrypt it ...)
I have to create a permission-system for this special user in Citrix
I have to put the special-user into a local-group on every server, to allow the remote-administration (security-risk)
I don't like to use PSSession
...
Is there a better/cleaner solution? Any ideas?

Start-Job with credential in custom task problems

I am trying to develop a custom task using Powershell which needs to use Start-Job -Cred to switch to another user in places. Agent is running as user A and I need to switch to user B. Logging in to the server running the agent as user A and then running the script works fine - the Start-Job switches credentials and runs a scriptblock as user B.
Running exactly the same thing from VSTS in the cloud using the same (on-prem) agent server running the agent as user A fails with the uninformative error:
"The background process reported an error with the following message: ."
I have done more debugging and there is no other error message anywhere. It seems to be related to the -Cred parameter of Start-Job as it makes no difference what is in the script block run and if I remove the -Cred parameter, it's also fine.
User A is in the Adminstrators group on the server running the agent
Agent runs as user A
Any ideas?
Try it with Invoke-Command, for example (output current user name):
$mypwd = ConvertTo-SecureString -String "[password, could use variable]" -Force -AsPlainText
$Cred = New-Object System.Management.Automation.PSCredential('[user name]',$mypwd)
$scriptToExecute =
{
$VerbosePreference='Continue'
Write-Output "$env:UserName"
# Write-Verbose "Verbose" 4>&1
}
$b = Invoke-Command -ComputerName localhost -ScriptBlock $scriptToExecute -Credential $Cred
Write-Output "Content of variable B"
Write-Host $b
Based on your experiences, your credentials are not being passed properly. Try this method and insert it into your script:
Outside of your script, get the securestring object-
Read-Host -AsSecureString | ConvertFrom-SecureString
Take the output of this command (where you enter the password), and put it before your start-job-
$Secure = ConvertTo-SecureString -String 'above output'
$Cred = New-Object System.Management.Automation.PSCredential('Username',$Secure)
Start-Job -Credential $Cred
The SecureString can be reversed by someone with know-how, but if the script and/or account is secure, then that doesn't matter.

Run powershell as another user

I can't wrap my head around this at all. I have a powershell script that works fine as long as the user has admin rights, because it is moving data to a NAS share that requires write permissions. My issue is I am putting the script in the GPO Startup process. So I need to run the powershell script as another user.
Do I somehow add the new user credentals inside the script itself, or use another process to runas the other user?
I've tried creating another .ps1 script to start the original script, but it didn't work.
I really want to be able to do this in the original script that's doing all the work.
$username = 'domain\user'
$password = 'password'
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList #($username,(ConvertTo-SecureString -String $password -AsPlainText -Force))
Start-Process -FilePath D:\Scripts\Monitor.ps1 -ComputerName localhost -Credential $cred
and I've tried:
Start-Process -FilePath D:\Scripts\Monitor.ps1 -ComputerName (NAS IP Address) -Credential $cred
This works fine inside a powershell script, so how do I get this to run as another user?
& D:\Scripts\monitor.ps1
We have decided to run this as a task under task scheduler at boot up run by a service account that has all the correct permissions. Not what I really wanted but it does work