Set-AzureRmVMCustomScriptExtension SecureExecution flag not working - powershell

We are running a custom powershell script against an Azure VM using the Set-AzureRMVMCustomScriptExtension command.
The ps script creates local user accounts provided with "username" and "password" parameters.
My understanding is that Set-AzureRMVMCustomScriptExtension supports -SecureExecution switch, which according to the documentation (https://learn.microsoft.com/en-us/powershell/module/azurerm.compute/set-azurermvmcustomscriptextension?view=azurermps-4.4.1&viewFallbackFrom=azurermps-4.4.0)
"Indicates that this cmdlet makes sure that the value of the Run parameter is not logged on the server or returned to the user by using the GET extension API. The value of Run might contain secrets or passwords to be passed to the script file securely."
However, providing the switch and executing the ps script results in the following being logged to the "Windows Powershell" event log on the target VM:
Engine state is changed from None to Available.
Details:
NewEngineState=Available
PreviousEngineState=None
SequenceNumber=13
HostName=ConsoleHost
HostVersion=5.1.14393.1770
HostId=
HostApplication=powershell -ExecutionPolicy Unrestricted -file createuser.ps1 -username myNewUser -password somePassword
EngineVersion=5.1.14393.1770
RunspaceId=
PipelineId=
CommandName=
CommandType=
ScriptName=
CommandPath=
CommandLine=
Which is not what I am expecting to see. Is this a bug? Or is the documentation incorrect?
This is the command I'm executing:
Set-AzureRmVMCustomScriptExtension -ResourceGroupName $vmResourceGroupName
-VMName $vmName
-StorageAccountName $scriptStorageAccountName
-ContainerName $scriptStorageAccountContainerName
-FileName $scriptName
-Run $scriptName
-Argument $scriptArguments
-Name $extensionAlias
-Location $location
-ForceRerun $(New-Guid).Guid
-SecureExecution

Well, its not like Azure can magically change how windows server operates. this is windows server logging, not extension logging. it won't log this to the extension log and will hide sensitive information from the api, but, obviously, powershell engine can log this input like any other input

Related

How do I run a command on localhost with saved credentials? -Powershell

I want to run one command with saved credentials on powershell, i have the following script
$user = "test"
$passwd = ConvertTo-SecureString -String "ExtremelyStrongPassword" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList $user, $passwd
Copy-Item -Path "C:\Temp\*" "C:\Program Files\Test\" -Credentials $cred
The user doesn't have administrator permissions, but in the localhost we have an user with administrator permissions to run these process.
The error returned is "Access Denied"
How do i pass these parameters to run a command with elevation?
Never pass plain text credentials in a script. Use the Get-Credential cmdlet to collect and use them. Even doing this, the user will get prompted for a password.
This is what the -RunAs switch of Start-Process is for
Or set your script to auto elevate
Or use the credential switch of a cmdlet
Or use a scheduled task with whatever creds you need, and let the user run it.
Use the Requires statement at the top of your script
Store the need creds in the Windows Credential Store and call them
from there
about_Requires - PowerShell | Microsoft Docs
Short description Prevents a script from running without the required
elements.
#Requires -RunAsAdministrator
Start-Process
Example 5: Start PowerShell as an administrator This example starts
PowerShell by using the Run as administrator option.
Start-Process -FilePath "powershell" -Verb RunAs
Using what you have this way:
Copy-Item -Path 'C:\Temp\*' 'C:\Program Files\Test\' -Credentials (Get-Credential -Credential 'Domain\UserName')
With exception of the scheduled task approach, each will prompt the user for a password, which sounds like what you wanting to avoid. So, consider the following:
Accessing Windows Credentials Manager from PowerShell
This simple PowerShell class can be used for working with Credentials
Manager and Password Vault in Windows: checking if account information
is present in the vault, saving credentials to the vault and reading
stored login and password information from the vault.
https://gallery.technet.microsoft.com/scriptcenter/Accessing-Windows-7210ae91
Using the registry to store credentials:
Save Encrypted Passwords to Registry for PowerShell

Trying to Log in to Azure in Powershell

I am following the MS guide located here and everything goes through correctly until I have to actually log in. The pop up window appears for my creds and validates them, but powershell doesn't seem to notice.
So it goes Install Module, Import Module, Verify Version, Log in. See below for what happens on the last two steps.
PS C:\WINDOWS\system32> Get-Module AzureRM -ListAvailable | Select-Object -Property Name,Version,Path
Name Version Path
---- ------- ----
AzureRM 6.3.0 C:\Program Files\WindowsPowerShell\Modules\AzureRM\6.3.0\AzureRM.psd1
PS C:\WINDOWS\system32> Connect-AzureRmAccount
Account :
SubscriptionName :
SubscriptionId :
TenantId :
Environment :
PS C:\WINDOWS\system32>
Of course, this prevents me from doing very much else with Azure from that point forward.
Edit: Issue appears on multiple workstations
I got this same issue. I have two users like many of you: the Azure user that is the "Work" account, and then the "Personal" account which is also created automatically by Office365 and Azure. I was getting the issue when I tried to use my "personal" account, in which I have some subscriptions added (delegated).
After trying lots, what worked for me was to login to the "Work" account when the "Connect-AzureRmAccount" command asks for an username/password. Then, I again use the command "Connect-AzureRMAccount", but this time I entered the personal account, and it finally worked.
Picture here
Edit: A better way I found later was this, as I manage a lot of subscriptions/tenants from a single account (delegated access):
Put the “tenantid” into a variable (you can get this ID on the Azure Portal, in my case, on the option to change directories):
How to get your tenant's IDs quickly
$tenantId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
Login specifying the TenantId:
Login-AzureRmAccount -TenantId $tenantId
Example 2
This behavior happens when you run
Clear-AzureRMContext -Scope CurrentUser
I'm not sure why and im attempting to debug on how to fix the issue. A work around is to close the powershell window and reopen a new powershell windows that does not have this command ran.
Running the command
Enable-AzureRmContextAutosave -Scope CurrentUser
Fixed the issue for me. This will autosave your context for every powershell session. If this is not desired you can run the command
Enable-AzureRmContextAutosave -Scope Process
which will save the azure context for only the process. Otherwise you will need to handle
You can try this...
Install-Module PoweshellGet -Force
Set-ExecutionPolicy -ExicutionPolicy Remotesigned
Install-Module AzureRm
Import-Module -Name AzureRm
Login-AzureRmAccount
You can use the below link to install latest PowerShell version:
https://github.com/Azure/azure-powershell/releases
And then use something like this in order to automatically pass in the username password, and skipping the UI:
$azureAccountName ="enter username here"
$azurePassword = ConvertTo-SecureString "password here" -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential($azureAccountName, $azurePassword)
Login-AzureRmAccount -Credential $psCred
Have you tried the following:
Import-Module Microsoft.Powershell.Security
$azureAccountName ="enter username here"
$azurePassword = ConvertTo-SecureString "password here" -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential($azureAccountName, $azurePassword)
$decrypt = $psCred.GetNetworkCredential()
$ptpass = $decrypt.Password
Write-Output "Logging in to Azure using $azureAccountName with a password of $ptpass"
Login-AzureRmAccount -Credential $psCred
If you receive an error with this code, please comment with the entire error message.
The only thing i can think of is the below
You maybe using Azure Service Management (Azure V1 / Azure Classic) which uses a different module to Azure Resource Manager (ARM , Azure V2).
To install Azure Service Management Module:
Install-Module Azure -AllowClobber
Allowing clobber because you already have AzureRM Module installed
Import Azure Module to PowerShell:
Import-Module Azure
Logs into ASM:
Add-AzureAccount
Shows you all subscriptions
Get-AzureSubscriptions
Selects the Subscription you allocate to work within
Select-AzureSubscription
Answered something similar in the below Thread:
Login-AzureRmAccount return subscription but Get-AzureSubscription return empty
Hope this helps
You can try logging in using the Service Principal credentials.
Service principal is an application created under Active Directory to which you can apply permission rules.
$pscredential = Get-Credential
Connect-AzureRmAccount -ServicePrincipal -ApplicationId "http://my-app" -Credential $pscredential -TenantId $tenantid
Refer here for more details.

Powershell command to export IIS websites and app pools of a remote server

I have the command which exports websites of the current logged in server (as below). I need the command to export websites of a different server.
%windir%\system32\inetsrv\appcmd list site /config /xml > c:\websites.xml
try with Invoke-Command
Note the syntax you have is for a dos command. The following should get you on track. Of course there is credentials you may have to pass in.
Remoting must be enabled on the remote servers Run Enable-PSRemoting -Force on each server.
Invoke-Command -Computer remoteserver -ScriptBlock {
& $Env:Windir\system32\inetsrv\appcmd.exe list site /config /xml
} | Out-File c:\websites.xml -Append
Note that the 'powershell' way of getting sites as powershell objects is shown here: https://stackoverflow.com/a/25091831/1165140

Elevate creditals with powershell via Local System Account

I want to deploy code using powershell via Jenkins Job. This works fine in the powershell ise.
$username = "mydomain\builder"
$password = "notmypassword"
$credentials = New-Object System.Management.Automation.PSCredential -ArgumentList #($username,(ConvertTo-SecureString -String $password -AsPlainText -Force))
$Arguments = "-ExecutionPolicy Bypass -File C:\Test.ps1 -NoNewWindow -WorkingDirectory C:\Windows\System32\WindowsPowerShell\v1.0 -NoLogo -NonInteractive"
Start-Process "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -Credential $credentials -ArgumentList $Arguments
But when I run it from Jenkins which use the local system I get the following error message.
Start-Process : This command cannot be run due to the error: Access is denied.
At C:\WINDOWS\TEMP\hudson5557889306949142167.ps1:7 char:1
+ Start-Process powershell.exe -Credential $credentials -ArgumentList $
If change I change the Jenkins service to another account it works. Why won't elevated permission work under the local system account?
note: the only code in test.ps1 is New-Item c:\scripts\new_file.txt
There seems to be a restriction on certain commands when a script is run under LocalSystem. This makes sense in terms of security, given that LocalSystem:
has complete unrestricted access to local resources. This is also the disadvantage of LocalSystem because a LocalSystem service can do things that would bring down the entire system.
Reference: MSDN, The LocalSystem Account
There is a similar question at SuperUser: Can not create process with elevated permissions from LocalSystem account with no answer so far a reference to this answer now.
There is a similar question at TechNet: Runing PowerShell script with the permissions of the LocalSystem user with answers suggesting to run the script via Task Scheduler.
I can think of using runas with /savecred and a /user:... with appropriate permissions whose password never expires. AFAIR you have to invoke runas with /savecred interactively once, enter the credentials and it will take the saved credentials from the next invocation onwards.

teamcity powershell - unable to run batch file

I've spent quite a bit of time banging my head on this one. A little StackOverflow help please, good folks!
Scenario: We are trying to run a custom .bat file located on the CI server via the TeamCity Powershell step.
When powershell script is run on local box manually, it kicks off .bat file correctly.
When powershell script is run through TeamCity, it successfully 'sees' the .bat file (validated by receiving a 'cannot find file' response when I rename the .bat file it is expecting)
HOWEVER, we have not seen any indication that the .bat file was actually kicked off.
What we've tried:
We've added the 'RedirectStandardOutput' and 'RedirectStandardError' for attempt to diagnose, but although the log file is created, it is returned blank.
We've granted filepath permissions and tried two different credentials including the credential of the TC build agent
Added "-wait" at one point to see if we needed to 'tell' PS to wait on the .bat file.
Two questions...
What is preventing us from running this .bat file?
How do we diagnose issues like this? ATM it is a 'blackbox' to us.
TeamCity Powershell settings:
Powershell Run Mode: Version 1.0; Bitness x64 (tried x86 as well)
Working Directory: Tried as blank, and specific filepath of .bat file (so, 'D:\folder\folder2\')
Script: Source Code
Script Execution: Execute .ps1 from external file (tried with 'Put script into PowerShell stdin with "-Command -" argument' as well)
Add -NoProfile argument (tried both)
Powershell script:
#Predefine necessary information
$Username = "DOMAIN\username"
$Password = "password"
$ComputerName = "CI Build Server Name"
#Create credential object
$SecurePassWord = ConvertTo-SecureString -AsPlainText $Password -Force
$Cred = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList $Username, $SecurePassWord
#Start batch file
Start-Process "testbat.bat" -WorkingDirectory D:\file\path\ -Credential ($Cred)-NoNewWindow -RedirectStandardError stderr.txt -RedirectStandardOutput stdout.txt
Write-Host "Executed powershell."
UPDATE 1: If we remove the '-Credential ($Cred)' portion we are able to kick off the testbat.bat file from TeamCity, as expected. The problem must lie with that "-Credential ($Cred)" argument, somehow. Any thoughts?
UPDATE 2: If we set the '-Credential ($Cred)' portion to the credential of the build agent user we are able to kick off the test.bat file from TeamCity. The problem only occurs when we set the credential to a user other than the one running the build agent. This seems to indicate that credential syntax is fine.
UPDATE 3: Tried running with PowerShell executionpolicy set to 'RemoteSigned' and 'Unrestricted'. Problem persists.
UPDATE 4: Gave the BuildAgent user, and the user of whom we want to run this as, full permissions to powershell via 'Set-PSSessionConfiguration'. Problem persists.
$credential = New-Object System.Management.Automation.PsCredential(".\user", (ConvertTo-SecureString "pass" -AsPlainText -Force))
Start-Process powershell -Credential $credential -ArgumentList '-noprofile -command &{Start-Process D:\file\path\test.bat -NoNewWindow -RedirectStandardError stderr.txt -RedirectStandardOutput stdout.txt }'
note:
first i get credential "user" ur user then convert your pass to plain text
then start-process with your credential set
If agent is running as service under Local System account, then it's not possible to run PowerShell under specified account. The workarounds are:
Run agent via command line.
Try to run agent service under another account (not Local System) with administrator rights, probably it will help.
Try RunAs plugin. It provides an ability to run builds under the specified user account.