Remote scripting credentials - powershell

I've a strange problem that I can't understand. Maybe someone will be able to explain it to me.
I'm trying to automate the installation of an app for SharePoint in a multitenant environment. I run the scripts on a remote machine like this:
$session = New-PSSession -Name "Install App Session" -Authentication Credssp -Credential $InstallAccountCredentials -ComputerName $frontend
$installAppScriptPath = Join-Path $currentScriptPath "\SharePoint\InstallApp.ps1"
$job = Invoke-Command -Session $session -FilePath $installAppScriptPath -ArgumentList $customerUrl, $env:COMPUTERNAME -AsJob
Wait-Job $job
Inside the InstallApp.ps1 I invoke the Import-SPAppPackage command but I get an "Access denied.
You do not have permission to perform this action or access this resource." error. However, if I login to the machine with exactly the same credentials that are used as $InstallAccountCredentials and start the script, everything is working perfectly fine. The account that is used for running this script is an tenant admin account.
Is there something I miss in invoking the command?

PowerShell remote doesn't work for a significant portion of the SharePoint cmdlets. Use the client object model instead - you can invoke those methods from PowerShell as needed.

Related

Enter-PSSession equivalent of $profile script

On my local PC and locally on the servers I admin, I regularly use the $profile script to set/output basic information. For instance running Set-Location to set the current path to the folder containing the scripts, and perhaps some Write-Host entries to show a basic cheat sheet for the most commonly used scripts and their expected parameters.
Does anyone know of a way to do something similar to that when using Enter-PSSession to connect interactively with a remote server?
As far as I can see there are no $profile files available with remote sessions, so I can't just add the commands in there (and the $profile used interactively on the local server doesn't get called when you remote into that same server).
Locally I've added functions to my local profile to make connecting to specific servers quicker, for example :
function foo{
$host.ui.RawUI.WindowTitle = "Foo"
Enter-PSSession -computername foo.local.mydomain.com -authentication credssp -credential mydomain\adminuser
}
and that works fine for connecting me (eg I type foo, then enter my password, and I'm in), but I still get dumped into C:\Users\adminuser\Documents.
I've tried adding things like the Set-Location command to the function after the connection, but that gets run in the local context (where the folder doesn't exist) and THEN it connects to the server. I even tried piping the commands to Enter-PSSession, but perhaps unsuprisingly that didn't work either.
Obviously things like Invoke-Command would allow me to specify commands to run once connected, but that wouldn't (as far as I can work out) leave me with an interactive session which is the primary aim.
You can't really automate unattended execution of anything that happens after Enter-PSSession connects your host to the remote session - but you can execute all the code you want in the remote session before calling Enter-PSSession:
function DumpMeInto {
param([string]$Path)
# Create remote session (you'll be prompted for credentials at this point)
$session = New-PSSession -ComputerName foo.local.mydomain.com -Authentication credssp -Credential mydomain\adminuser
# Run Set-Location in remote runspace
Invoke-Command -Session $session -ScriptBlock { Set-Location $args[0] } -ArgumentList $Path
# ... and then enter the session
Enter-PSSession -Session $session
}
Now you can do DumpMeInto C:\temp and it should drop you into a remote session on foo.local.mydomain.com with it's working directory set to c:\temp

Is it possible to host an "always running" powershell remoting process?

I'm researching whether it's possible to host an always-running Powershell remoting process.
By default, PSRemoting will start a process as the authenticated user.
However, using custom PS Session Configurations, it's possible to set a "run as account" that will ensure that the remote process (on the server, so to speak) always runs as a "known" user, regardless of the identify of the connecting client.
The reason for me researching this, is that I notice that Ansible runs quite slowly against windows servers, and I suspect this is due to the fact that the remoting process on the server gets spun up with each command Ansible sends. I'd like to see if it's possible to have an always-running process that is "ready" in order to speed up executions.
This is as far as I've gotten:
$ansiblecred = get-credential
New-PSSessionConfigurationFile `
-path "C:\sessionconfig.pssc" -SessionType Default `
-RequiredGroups #{ And = 'Administrators' }
Unregister-PSSessionConfiguration -Name ansible -force
Register-PSSessionConfiguration `
-Path "C:\sessionconfig.pssc" -Name ansible `
-RunAsCredential $ansiblecred -AccessMode Remote `
-UseSharedProcess -ThreadOptions ReuseThread
restart-service winrm
$remotecred = Get-Credential
$i = 0
while ($i -lt 10)
{
#This is slow because the remoting session is setup/teard down every time
Invoke-Command -ComputerName "localhost" -Credential $remotecred -Authentication Basic -ScriptBlock {$env:computername} -ConfigurationName ansible
$i ++
}
Even tho I'm connecting to the session with a different credential, the actual process runs as the "service" credential, so that part's good.
However, it seems to be still spinning up and down the process on each execution.
Just for clarification: The client here is not regular Powershell, it's client which will interact directly with the wsman service over http. So while I appreciate all responses, suggestions based around client-side Powershell code (such as new-pssession, invoke-command etc) are not gonna help :-|
Any pointers would be appreciated here, I'm trying to get to a place where the remoting process simply lives regardless of sessions being executed or not. Is this possible?
Create a session outside and use it in the loop.
$Session = New-PSSession -ComputerName $Server -ConfigurationName MyConfiguration
While(1){
Invoke-Command -Session $Session -Credential $remotecred -Authentication Basic -ScriptBlock {'my code'}
sleep 10
}

Invoke-Command doesn't work but Get-Service does

I'm having a bit an issue invoking a command to remotely turn off services via PowerShell. I'm successful when using
(Get-Service -Name tomee -ComputerName servernamefqdn).Stop()
However when using
Invoke-Command -ComputerName servernamefqdn -Credential $creds -ScriptBlock {
(Get-Service -Name tomee).Stop()
}
I get errors
enter-pssession...winrm cannot process
and
The following error occurred while using Kerberos authentication: Cannot find the computer servernamefqdn.
I'm using my own credentials to pass in invoke. I've already ran the quick config for WinRM and added trusted sites for all. I'm not understanding why the first command works but the invoke command doesn't seem to find the server. The goal is the script will remotely stop services using another account. I read 1 other person having this same issue but no real solution for me. Any ideas?

Powershell script using another user account

I'm not very good with powershell (to be honest, I'm bad !) but I need to do a script which download pictures and store them in a specific shared folder. I can download the pictures easily, but the folder where I need to store them is protected and there's is only one user (created specifically) who has access on it.
So my question is : how can I configure my script to use this user credentials ? I searched on the net, but I can't understand. As I said, I'm not a powershell user, and I use OS X at home, so I'm not even good with Windows rights and permissions. So a clear and easy answer would be really appreciated !
Thank's !
Use the Invoke-Command command with the -Credential and -ScriptBlock parameters to launch a PowerShell ScriptBlock as a different account. I believe that you will also need to enable PSRemoting in order for Invoke-Command command to work, even on the local system.
$Credential = Get-Credential;
$ScriptBlock = { Copy-Item -Path c:\test\test.txt -Destination c:\test2\test.txt; };
Invoke-Command -Credential $Credential -ScriptBlock $ScriptBlock;
A more complicated solution would be to use the Start-Process cmdlet with the -Credential parameter, to kick off an external executable under an alternate credential. If you just want to kick off PowerShell code though, you're better off using Invoke-Command.
$Credential = Get-Credential;
$Executable = 'c:\path\to\file.exe';
Start-Process -FilePath $Executable -Credential $Credential -Wait -NoNewWindow;

Invoke-Command and Start-Process Issues

I'm trying to execute the following script:
$Cred = Get-Credential
Invoke-Command -Computername Localhost -Cred $Cred -Scriptblock {Start "Notepad.exe" -Wait}
Well, the notepad comes up no problem as Administrator but it is not visible in the current user's account.
I think it's not possible to see gui in an interactive session with different credential, it live in another user session.
Workaround:
start-process notepad.exe -Credential $Cred
I've run into this problem with PS Remoting and could not find a way to get an app running under one set of credentials to show up on the interactive desktop of a different user. I eventually gave up and used SysInternals utility psexec along with its -i parameter.