Powershell incorrect running sequence - powershell

Kinda new to powershell and trying to write scripts in general. Im trying to create a script that creates an AD user and then assigns that user a license.
However doesn't seem to matter what I do, the sync command I have doesnt execute before the waiting period; so it cant find the user to assign the license to.
Any ideas what Im getting wrong?
`$DCSync = 'DC01'
#Starts AD Sync
Invoke-Command -ComputerName $DCSync -scriptblock {
Import-Module ADSync
Start-ADSyncSyncCycle -PolicyType Delta
Write-Output "testing"
}
send-mailmessage -From "abc#test123.co.uk" -To "abcHelpdesk#test123.co.uk" -Subject "New user creation" -Body "Please connect to DC01 and authenticate to Office 365 to complete the user setup for $UserPrincipalName" -SmtpServer [REDACTED]
Start-Countdown -Seconds 5 -Message "Synchronizing changes to Office 365"
#Install-Module PowerShellGet
#Install-Module Microsoft.Graph -Scope CurrentUser
#Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Connect-MgGraph -Scopes User.ReadWrite.All, Organization.Read.All
$MgUserID = Get-MgUser -UserId "$EmailAddress"
Update-MgUser -UserId "$MgUserID" -UsageLocation GB
Set-MgUserLicense -UserId $MgUserID -AddLicenses #{SkuId = "6fd2c87f-b296-42f0-b197-1e91e994b900" } -RemoveLicenses #()`
Write-Outpost "testing" always prints after the ADsync commands
Creating a user - assigning a license to newly created user
It just errors out because its not syncing to AD using the command so the user doesn't 'exist' yet

A couple of thoughts:
Try using Start-Sleep rather than Start-Countdown
If it isn't asynchronous, you can try running Start-ADSyncSyncCycle -PolicyType Delta using the -AsJob parameter, and then retrieve the status of that job using a while loop and not proceeding until the job is completed
If you have the e-mail address, then you can use a while loop to not proceed until the account is created, like:
while ($null -eq $MgUserID){
try {
$MgUserID = Get-MgUser -UserId "$EmailAddress"
}
catch {
$MgUserID = $null
}
Start-Sleep -Seconds 30
}

Related

Start-Job connecting to Exchange Online

I need to run parallel Search-Mailbox cmdlets against 100's mailboxes to delete the content but they need to fit certain parameters first like certain CAS protocols enabled and a forwarding address present. I've also parameterised it so I can pass a $maxJobCount int to it so the runner can specify a maximum number of concurrently running jobs to allow so as to account for resources on their machine.
Got the thing working then got to the start-job component which is a pretty simple function.
function _StartJob {
param (
$mailAddress
)
Start-Job -Name $mailAddress -Scriptblock {
Get-EXOMailbox $mailAddress -PropertySets Delivery
}
}
That's returning an error saying I need to run Connect-ExchangeOnline before using the cmdlets which is where I learned script blocks in Start-Job are actually new PowerShell.exe processes so don't inherit modules and session options.
Does anyone know an easier way around this? In an MFA environment, it either means sitting there and pasting the password in a few hundred times or convincing the Change board and Secops dept to let me setup a graph application with delete rights... both painful
Thanks for any advice
You just have to pass in the creds into the block however you want.
$kvCertName = 'Cert'
#I am using azure automation here to get the cert its different for keyvault
$kvCertPFX = Get-AutomationCertificate -Name $kvCertName
$tenantid = 'yourcompany.onmicrosoft.com'
$appid = '00000000-46da-6666-5555-33333cfe77ec'
$startDate = ([datetime]::Today).AddDays(-7)
#Build the script block
$block = {
Param(
$kvCert,
$appID,
$tenantID,
$n,
$startdate
)
$newCertPFX = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($kvCert)
Connect-ExchangeOnline -Certificate ([System.Security.Cryptography.X509Certificates.X509Certificate2]$newCertPFX) -AppID $appID -Organization $tenantID -ErrorAction Stop
Search-AdminAuditLog -StartDate $startDate.adddays($n) -EndDate $($startDate.AddDays($n) | get-date -Hour 23 -Minute 59 -Second 59) -ExternalAccess:$false -ResultSize 250000
Disconnect-ExchangeOnline -confirm:$false
}
#Remove all jobs created
Get-Job | Remove-Job
#Run All the Parrallel Jobs
$num = 0..6
$kvCert = $kvCertPFX.Export(3)
foreach($n in $num){Start-Job -Scriptblock $Block -ArgumentList #($kvCert,$appID,$tenantid,$n,$startdate)}
#Wait for all jobs to finish.
do {start-sleep 1}
until ($(Get-Job -State Running).count -eq 0)
#Get information from each job.
$adminPowerShellAuditLog = $null
foreach($job in Get-Job){$adminPowerShellAuditLog+= Receive-Job -Id ($job.Id)}
Write-Output $adminPowerShellAuditLog

canceling get-credentials in loop

I am working on developing PowerShell script to automate a task on a remote server by using Invoke-Command with WinRM.
The script will take the server IP, test WinRM and "Get-Credential" cmdlet to establish session and use Invoke-Command to run another script on remote server. I have made significant progress of what I want to achieve, however, I am having trouble on how to setup the code so that when I press the "Cancel" or "X" button on Get-Credential prompt it should abort the script and return to the regular PowerShell command line prompt.
Below is what I have so far, I have erased the comments and description of the code to keep the number of words less in here.
function SS
{
Add-Type -AssemblyName System.Windows.Forms
$BInput = [System.Windows.Forms.MessageBox]::Show('Do you want to proceed?', 'Confirmation',[System.Windows.Forms.MessageBoxButtons]::YesNo)
switch ($BInput)
{
"Yes" {
while ($true)
{
$server=Read-Host "Enter Server IP Address"
set-item -Path WSMan:\localhost\Client\TrustedHosts -Value "$server" -Force
if(Test-WSMan -ComputerName $server -ErrorAction SilentlyContinue)
{
Write-Host "$server is accessible, enter credentials to connect"
while ($true)
{
$creden=Get-Credential -Message "Please enter the server credentials that you want to connect"
$serversession = New-Pssession -ComputerName $server -Credential $creden -ErrorAction SilentlyContinue
if(-not($serversession))
{
write-warning "Credentials are not valild, please try again"
}
else
{
write-host "$server is connected, starting the workflow ......"
Invoke-Command -Session $serversession -FilePath "C:\Temp\XXX.ps1"
}
}
Break
}
else
{
write-host "Windows Remote Management (WinRM) protocol is not running, please check service and confirm."
}
}
Get-Pssession | Remove-PSSession
}
"No" {
Break
}
}
}
I understand I have to apply the changes / logic after this line
$creden=Get-Credential -Message "Please enter the server credentials that you want to connect"
But can't seem to find it yet. I looked online and have taken different approaches but no success so far. I would like to have opinions or recommendations on how to tackle this, appreciate your help.
Thanks
What i'm seeing is that you may be thinking too much into it. A simple if statement should do the trick, try:
$creden=Get-Credential -Message "Please enter the server credentials that you want to connect"
if(!$creden){break}
Continuing from my comment.
Try this refactor of your use case.
Point of note: Note fully tested since I do not have an environment at this time to test.
Function Start-WorkFlow
{
<#
.Synopsis
Execute a workflow
.DESCRIPTION
Sets up a WinRM session to a remote host to execute the defined workflow
.EXAMPLE
Start-WorkFlow
.EXAMPLE
swf
.INPUTS
Remote host IPAddress
Remove host credentials
.OUTPUTS
Resutls of teh workflow
.NOTES
V 0.0.1 - Prototype script. Clean-Up before production use
.COMPONENT
Stand-alone script
.ROLE
Administrative actions
.FUNCTIONALITY
Implemetned error logic for each code block
Restrict the user input to only be a proper IPAddress
Validate TCPIP state
Validate WSman state
Establish a new session
Process workflow
Exit session
#>
[cmdletbinding(SupportsShouldProcess)]
[Alias('swf')]
Param
(
)
If ((Read-Host -Prompt 'Do you want to proceed: [Yes/No]') -eq 'No' )
{Break}
Else
{
Do {$RemoteServerIPAddress = (Read-Host -Prompt 'Enter Server IP Address')}
Until ($RemoteServerIPAddress -match "^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$")
Get-ChildItem -Path 'WSMan:\localhost\Client\TrustedHosts'
Try
{
(Test-Connection -ComputerName $RemoteServerIPAddress -Count 1 -ErrorAction Stop).IPV4Address
# Set-Item -Path 'WSMan:\localhost\Client\TrustedHosts' -Value $RemoteServerIPAddress -Force
Get-ChildItem -Path 'WSMan:\localhost\Client\TrustedHosts'
Try
{
Test-WSMan -ComputerName $RemoteServerIPAddress -ErrorAction Stop
"$RemoteServerIPAddress is accessible, enter credentials to connect"
Do
{
$Creds = $null
$CredMesssage = 'Please enter the remote server credentials that you want to connect.'
$CredMesssage = "$CredMesssage If credentials are not valid, you will be prompted to re-enter them."
$Creds = Get-Credential -Message $CredMesssage
if(-Not $creds)
{
Write-Warning -Message 'Credential request cancelled.'
Start-Sleep -Seconds 3
Exit
}
$NewPSSessionSplat = #{
ComputerName = $RemoteServerIPAddress
Credential = $Creds
Name = 'RemoteSessionName'
ErrorAction = 'Stop'
}
New-PSSession $NewPSSessionSplat
}
Until (Get-PSSession -Name 'RemoteSessionName')
"$RemoteServerIPAddress is connected, starting the workflow ......"
Invoke-Command -Session $RemoteServerSession -FilePath 'C:\Temp\XXX.ps1'
}
Catch
{
Write-Warning -Message 'Session connection results:'
$PSitem.Exception.Message
}
Finally
{
Get-PSSession |
Remove-PSSession -ErrorAction SilentlyContinue
}
}
Catch
{
Write-Warning -Message "
The remote server $RemoteServerIPAddress is not available
Exiting the session."
Start-Sleep -Seconds 3
Exit
}
}
}
Start-WorkFlow

Import-PSSession - throwing credentials-mask

I got a problem with a powershell-script used in our domain to create new users:
Helpdesk will call a .bat as administrator, this bat calls a script-file to automate the creation. In this script, two sessions are created and imported, to use the Exchange- and AD-cmdlets locally.
During/after the import a second/third credential-mask gets thrown, but clicking "cancel" will do nothin, the script will run through without any issues. Nevertheless this annoys the helpdesk..
When running the .ps1 directly from the ISE, the mask won't be shown. Also, when C&Ping the Create-/Import part of the script to a new file and calling it the same way as before also won't show these mask..
Here a part of the .ps1-file:
<#
.DESCRIPTION
Creates a new standard user
.NOTES
Requires : Exchange 2016 Remote Session
Req.OS Version : not tested
Req.PS Version : not tested
.EXAMPLE
Create-User.ps1 -datapath \\path\to\userdata.csv -credentialobject $cred
#>
Param (
[string]$datapath, <#Folder where the CSVs sit #>
[System.Management.Automation.CredentialAttribute()]$credentialobject = $null
)
#region SET global var definitions
$ErrorActionPreference = "Continue"
Start-Transcript -path $ScriptLogPath # | out-null
#endregion
#region SET var definitions
$userfile = "$datapath\userdata.txt"
$groupfile = "$datapath\groupdata.txt"
#Exchange
$MSXremotingserver = "exchangehostname"
$MSXdatabasenames = #("msx_db")
#AD
$domaincontroller = "dchostname"
$ADremotingserver = $domaincontroller
$BaseDN = "OU=Users,DC=domain,DC=local"
#endregion
#region Import Userdata
# CSV's are getting imported here - WORKING
#endregion
#region INIT Remotesession
#Get AD Creds / use given AD Creds
if (($credentialobject -ne $null) -and (($credentialobject.GetType()).name -eq "PSCredential")){
$UserCredential = $credentialobject
}else{
$UserCredential = Get-Credential
# Get credentials to create the remote-sessions. Seems to be working.
}
$MSXSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionURI http://$MSXremotingserver/powershell -Credential $UserCredential
echo "import..."
$null = Import-PSSession $MSXSession -AllowClobber -DisableNameChecking # | out-null
# After the import (Progress bars running through on top of the PS) another credential-mask appearing, "Cancel" makes the script run through without further errors.
echo "OK"
$ADSession = New-PSsession -Computername $ADremotingserver -Credential $UserCredential
Invoke-Command -Command {Import-Module ActiveDirectory -DisableNameChecking} -Session $ADSession # | out-null
echo "import..."
Import-PSSession -Session $ADSession -Module "ActiveDirectory" -Prefix Remote -AllowClobber -DisableNameChecking # | out-null
# After the import (Progress bars running through on top of the PS) another credential-mask appearing, "Cancel" makes the script run through without further errors.
echo "OK"
#AD-user already existing?
if ([bool](get-remoteaduser -LDAPFilter "(SamAccountName=$($userdata.Kuerzel))")){
#Throw custom error - AD-User bereits vorhanden!
}
#build Account...
# AD-user and Mailbox are created and configured. WORKING!
#endregion
#region END Script
Get-PSSession | Remove-PSSession
Stop-Transcript
Write-Host "Beende Skript..."
start-sleep -Seconds 3
exit 10000
#endregion
And here's how the .ps1 is being called:
%systemroot%\System32\WindowsPowerShell\v1.0\powershell.exe -executionpolicy bypass -file \\helpdeskserver\powershell_userdata$\Create-User.ps1 \\helpdeskserver\path\to\csv"
I don't know what to do. Tried many different versions of each command, tried piping the in/output, nothing will do..
Google doesn't seem to know that behaviour, neither anyone here on Stackoverflow..
Thanks for any tips and help, I'll apprechiate!
Regards, Ting3l
Edit: When starting the .bat-file without administrative rights (Or with right-click -> other user.. -> admin-account) the second/third credential-dialog won't appear, instead I get an "Index out of range"-exception.
Maybe it's unimportant, but you can try to exit the session by Exit-PSSession. After that use exit 1000. Becoaser when you use exit in the session it completes the session (wherein all code after will be ignored, but script will have successful completed)

Kerberos error in long running Exchange powershell skript after 10 hours

I implemented a powershell script, which assigns Exchange settings to our user mailboxes (Exchange 2016). As we have a lot of mailboxes and assigning settings is slow, the script would run more then 15 hours. However after about 10 hours I get the following error:
Processing data for a remote command failed with the following error message: Error occurred during the Kerberos response.
[Server=XXXXX, TimeStamp = 74/2018 01:25:49]
For more information, see the about_Remote_Troubleshooting Help topic.
At C:\Users\ACCOUNT\AppData\Local\Temp\tmp_cj3akhk4.osq\tmp_cj3akhk4.osq.psm1:77943 char:9
+ $steppablePipeline.End()
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (XXXX:String) [], PSRemotingTransportException
+ FullyQualifiedErrorId : JobFailure
+ PSComputerName : XXXX
My script retires the operation and after two retries (which fail) an authentication prompt is shown. There I can enter the password of the service account and the script continues. However this dialog is only visible if I run the script in a PS command prompt. If the script is started as Windows Task, it just hangs and does not continue.
The connection to Exchange is opened and imported with the following code. The code can either connect to our on premises Exchange or Exchange online based on the passed parameter. The problem is currently only happening, when connected to our local (on premises) Exchange infrastructure.
Function Connect-Exchange{
PARAM(
[parameter(Mandatory=$false)]
[String]$TargetExchange = 'Local'
)
BEGIN{}
PROCESS{
if ($ExchangeSessionInfo.Session -and $ExchangeSessionInfo.Type -eq $TargetExchange -and $ExchangeSessionInfo.Session.State -eq 'Opened'){
# Nothing to do, we are already connected.
Write-Log "Exchange connection type $($TargetExchange) already established, nothing to do."
} else {
if ($ExchangeSessionInfo.Session -and $ExchangeSessionInfo.Type -ne $TargetExchange -and $ExchangeSessionInfo.Session.State -eq 'Opened'){
# We have a open session with the wrong type. We close it.
Remove-PSSession $ExchangeSessionInfo.Session
$ExchangeSessionInfo.Session = $null
$ExchangeSessionInfo.Status = 'undefined'
$ExchangeSessionInfo.Type = ''
}
# We close all other existing Exchange sessions we created.
get-pssession -Name "Exchange" -ErrorAction SilentlyContinue | remove-pssession
# Now connect to the requestes Exchange infrastructure and import session.
$Connected = $False
$RetryCount = 5
do{
try {
If ($TargetExchange -eq 'Local'){
$ExchangeServer = Get-Random -InputObject $LocalExchangeConfig.ExchangeServers
$ExchangeSessionInfo.Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "http://$($ExchangeServer)/PowerShell/" -Credential $EOCredentials -Authentication Kerberos -Name "Exchange"
} else {
$ExchangeSessionInfo.Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri 'https://ps.protection.outlook.com/powershell-liveid/' -Credential $EOCredentials -Authentication Basic -AllowRedirection -Name "Exchange"
}
$Res = Import-PSSession $ExchangeSessionInfo.Session -WarningAction SilentlyContinue -AllowClobber
# Store Exchange status in session variable.
$Connected = $True
$ExchangeSessionInfo.Status = 'connected'
$ExchangeSessionInfo.Type = $TargetExchange
} catch {
$err = Write-Error -err $error -msg "Could not connect to Exchange server type '$($TargetExchange)' (Retries left: $($RetryCount))." -Break $false
get-pssession -Name "Exchange" -ErrorAction SilentlyContinue | remove-pssession
$RetryCount -= 1
}
} while (!$Connected -and ($RetryCount -gt 0))
# If we do not have connection here, this is an error.
if (!$Connected) {
$ExchangeSessionInfo.Session = $null
$ExchangeSessionInfo.Status = 'undefined'
$ExchangeSessionInfo.Type = ''
throw "No connection to Exchange server (type: $($TargetExchange)) could be established."
} else {
# Get list of available mailbox DBs including mailbox count and create hashtable to store statistics. We only have to get it the first time.
if (($MailboxDBList.count -eq 0) -and ($TargetExchange -eq 'Local')){
Write-Log "Getting current Exchange DB configuration and mailbox count. Takes a moment."
$MailboxDBList = Get-MailboxDBCount -Type $LocalExchangeConfig.DistributeMailboxes
}
}
}
}
END{
return $ExchangeSessionInfo
}
}
The following code is applying a predefined set of Exchange settings:
...
$TryCount = 0
$Done = $false
do{
# It takes a while after enabling mailbox until settings can be applied. So we need to retry.
try{
# If we need to execute a setting several times.
if ($MailboxSetting.LoopOver){
# We have a loop value (array).
foreach ($LoopValue in $MailboxSetting.LoopOver){
# Copy parameter as we have to change a value (loop value).
$TempParams = $Params.PsObject.Copy()
#($Params.getenumerator()) |? {$_.Value -match '#LOOPVALUE#'} |% {$TempParams[$_.Key]=$LoopValue}
$res = & $MailboxSetting.Command -ErrorAction Stop #TempParams -WhatIf:$RunConfig.TestMode
}
} else {
# THE PROBLEM HAPPENS HERE
$res = & $MailboxSetting.Command -ErrorAction Stop #Params -WhatIf:$RunConfig.TestMode
}
# Write-Log "Setting command $($MailboxSetting.Command) executed successfully"
$Done = $true
} catch{
$tryCount++
$res = Write-Error -err $error -msg "Error applying mailbox settings, account: $($AccountDetails.sAMAccountName), retry count: $($TryCount)" -Break $false
Start-Sleep -s $(($Retires-$TryCount) * 5)
}
} while ((!$done) -and ($tryCount -lt $Retires))
...
I am sure the error is not related to the code, because the script runs for hours without a problem and applies all settings. However after a around 10 hours it seems the Kerberos ticket expires and then the script cannot longer access Exchange without a re-login.
Is there a way to keep the Kerberos ticket from expiring or renew it?
Any help would be appreciated.
I think you are hitting the domain security policy (group policy object - GPO) => security settings/account policy/Kerberos policy restriction.
The two valid options for you are:
Maximum lifetime for user ticket => the default value is 10 hours
Maximum lifetime for user ticket renewal => the default value is 7 days (this is the period within which the ticket can be renewed).
Is there a way to keep the Kerberos ticket from expiring or renew it?
For the first questions you "just" need to adjust the maximum lifetime for user ticket setting to value as you deem appropriate.
The second one is more tricky. I would just purge all kerberos tickets via the powershell. For more - viewing and purging cached kerberos tickets which would get you a new one.
If the ticket can be renewed you have to check the RENEABLE flag - you wan view it via kinit. Perhaps kinit -R could be enough for ticket renewal. (I did not do this my self) You could also renew it via kerberos for windows
Edit -- adding klist purge to purge all Kerberos tickets so it can be renewed.
As you have klist then you can purge all tickets via must be run in elevated powershell prompt
(all credits to JaredPoeppelman):
Get-WmiObject Win32_LogonSession | Where-Object {$_.AuthenticationPackage -ne 'NTLM'} | ForEach-Object {klist.exe purge -li ([Convert]::ToString($_.LogonId, 16))}
Then check if your TGT was updated via:
klist tgt
Note: you must use FQDN name everywhere!
Thanks for your suggestion. In a first try I will extend my code as follows and try to reestblisch a new Exchange connection. Needs 10 h runnig the script in order to see if this works.
I am not able to influence the domain security Policy, additionally as I do not know how long the script runs, it will be difficult to set a value.
On my Windows 2016 the command "kinit" ist not recognized. Possibly I need to install additional modules/roles.
...
$TryCount = 0
$Done = $false
do{
# It takes a while after enabling mailbox until settings can be applied. So we need to retry.
try{
# If we need to execute a setting several times.
if ($MailboxSetting.LoopOver){
# We have a loop value (array).
foreach ($LoopValue in $MailboxSetting.LoopOver){
# Copy parameter as we have to change a value (loop value).
$TempParams = $Params.PsObject.Copy()
#($Params.getenumerator()) |? {$_.Value -match '#LOOPVALUE#'} |% {$TempParams[$_.Key]=$LoopValue}
$res = & $MailboxSetting.Command -ErrorAction Stop #TempParams -WhatIf:$RunConfig.TestMode
}
} else {
$res = & $MailboxSetting.Command -ErrorAction Stop #Params -WhatIf:$RunConfig.TestMode
}
# Write-Log "Setting command $($MailboxSetting.Command) executed successfully"
$Done = $true
} catch{
$tryCount++
$res = Write-Error -err $error -msg "Error applying mailbox settings, account: $($AccountDetails.sAMAccountName), retry count: $($TryCount)" -Break $false
Start-Sleep -s $(($Retires-$TryCount) * 5)
try{
# We may have lost the Kerberos ticket, reconnect to Exchange.
$ConnectionType = $ExchangeSessionInfo.Type
Disconnect-Exchange
Connect-Exchange -TargetExchange $ConnectionType
} catch {}
}
} while ((!$done) -and ($tryCount -lt $Retires))
...

Monitoring Services on an Azure VM using an Azure Runbook

I have a Powershell script that enumerates running services and their current state using Get-WmiObject Win32_Service. Initial version based on this one and then modified for Azure. When I run the script in Powershell (without the azure automation parts) on my location machine it works fine and I can connect to all the machines of interest, but when I port it to a runbook i get the following error: "Get-WmiObject : The RPC server is unavailable."
Q: Is the problem with permissions for the automation account? If so, what account should I add to the local machines to resolve the issue?
Q: Is Get-WmiObject not a valid way to initiate the connection? If not, what should I try instead?
The code I'm using is below:
[CmdletBinding(SupportsShouldProcess = $true)]
param(
# Servers to check
[Parameter(Mandatory=$true)][string[]]$ServerList,
# Services to check for
[Parameter(Mandatory=$true)][string[]]$includeService
)
# Following modifies the Write-Verbose behavior to turn the messages on globally for this session
$VerbosePreference = "Continue"
$connectionName = "AzureRunAsConnection"
# retry
$retry = 6
$syncOk = $false
$servicePrincipalConnection = Get-AutomationConnection -Name $connectionName
do
{
try
{
Add-AzureRmAccount -ServicePrincipal -TenantId $servicePrincipalConnection.TenantId -ApplicationId $servicePrincipalConnection.ApplicationId -CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
$syncOk = $true
}
catch
{
$ErrorMessage = $_.Exception.Message
$StackTrace = $_.Exception.StackTrace
Write-Warning "Error during sync: $ErrorMessage, stack: $StackTrace. Retry attempts left: $retry"
$retry = $retry - 1
Start-Sleep -s 60
}
} while (-not $syncOk -and $retry -ge 0)
Select-AzureRMSubscription -SubscriptionId $SubscriptionId -TenantId $servicePrincipalConnection.TenantId
$currentSubscription = Get-AzureRMSubscription -SubscriptionId $SubscriptionId -TenantId $servicePrincipalConnection.TenantId
Set-AzureRmContext -SubscriptionId $SubscriptionId;
$props=#()
[System.Collections.ArrayList]$unreachableServers = #()
Foreach($ServerName in ($ServerList))
{
try
{
$service = Get-WmiObject Win32_Service -ComputerName $servername
}
catch
{}
if ($Service -ne $NULL)
{
foreach ($item in $service)
{
#$item.DisplayName
Foreach($include in $includeService)
{
#write-host $include
if(($item.name).Contains($include) -eq $TRUE)
{
$props += [pscustomobject]#{
servername = $ServerName
name = $item.name
Status = $item.Status
startmode = $item.startmode
state = $item.state
serviceaccount=$item.startname
DisplayName =$item.displayname}
}
}
}
}
else
{
Write-host "Failed to contact server: "$ServerName
$unreachableServers.Add($ServerName)
}
}
$props | Format-Table Servername,Name,startmode,state,serviceaccount,displayname -AutoSize
I am assuming that you are using the Azure Automation Hybrid Worker functionality. Be default it runs under the System account. However you can use a different account to run the runbook under. This is documented here: Azure Automation Hybrid Worker; Look under the RunAs account section. Use the same account that works when you try it directly.
have you considered using OMS? this sounds like a better thing to do.
Anyway, to answer your questions, I would probably create a local user and create a PS configuration endpoint for that user to connect to, and connect impersonating that user from the Automation Account, but again, I wouldn't even go this route, I'd rather use OMS.