I have a list of 5 Servers and for specific reasons they are not on the domain. The credentials among them are the same.
I am trying to remotely kill any instance of a process on the machines. For this website I have change the process to notepad.exe
I am having issues trying to determine how to successfully connect to these boxes.
I am running
$StartCheck = Get-WmiObject Win32_Process -Computer $Servers |
Where-Object { $ProcessNames -contains $_.Name }
$StartCheck | FT * -a;$StartCheck | FT * -a | out-file -FilePath $logfile -Append
and Here.
(Get-WmiObject Win32_Process -Computer $Servers |
Where-Object { $ProcessNames -contains $_.Name }).Terminate() | out-null
I am faced with the following error
Get-WmiObject : Access is denied. (Exception from HRESULT: 0x80070005
(E_ACCESSDENIED))
At C:\Users\first.last\Desktop\Kill All Traffic Managers.PS1:67 char:13
+ $EndCheck = Get-WmiObject Win32_Process -Computer $Servers |
+
What is the easiest way to enter the credentials?
Add this to your script and change usernname and P#ssw0rd
$account = "username"
$PASSWORD = ConvertTo-SecureString P#ssw0rd -AsPlainText -Force
$UNPASSWORD = New-Object System.Management.Automation.PsCredential $account, $PASSWORD
Also change your
Get-WmiObject Win32_Process -Computer $Servers`
for
Get-WmiObject Win32_Process -Computer $Servers -Credential $UNPASSWORD
Related
I am trying to script a powershell function manage-bde.exe (bitlocker) to add a key protector to systems without TPM. For some reason GPO is not working. I have not had any luck getting powershell to add the protector remotely. I can log on to the endpoint and use the built in wizard to encrypt and save the key to our repository but for some reason remote automated scripting eludes me. My question is really more of guidance. Can powershell only be used, to remotely manage systems with TPM? I have bitlocker enabled and encrypted on systems without but I have had to do it manually.
Start-Transcript -Path ".\bitlockertranscript.txt" -Force
foreach ($Computer in $List) {
if (test-Connection -ComputerName $Computer -Count 1 -Quiet ) {
Get-ADComputer -Identity $Computer -Property * | Select Name,OperatingSystem
Get-WmiObject -class Win32_Tpm -namespace root\CIMV2\Security\MicrosoftTpm -computername $Computer | fl IsActivated_InitialValue, IsEnabled_InitialValue, IsOwned_InitialValue
$BitLocker = Get-WmiObject -ComputerName $Computer -Namespace Root\cimv2\Security\MicrosoftVolumeEncryption -Class Win32_EncryptableVolume
$id = $BitLocker.GetKeyProtectors(3).volumekeyprotectorid | Select -First 1
manage-bde.exe -cn $Computer -protectors -adbackup c:
manage-bde.exe -on C: -cn $Computer
Invoke-GPUpdate -Target $computer
} else
{"No Connection to $Computer"
}
}
Stop-Transcript
Invoke-WMIMethod -ComputerName $computer -Namespace root\ccm -Class SMS_CLIENT -Name TriggerSchedule "{00000000-0000-0000-0000-000000000026}" | Out-Null
Invoke-WMIMethod -ComputerName $computer -Namespace root\ccm -Class SMS_CLIENT -Name TriggerSchedule "{00000000-0000-0000-0000-000000000027}" | Out-Null
Invoke-WMIMethod -ComputerName $computer -Namespace root\ccm -Class SMS_CLIENT -Name TriggerSchedule "{00000000-0000-0000-0000-0000000000113}" | Out-Null
Invoke-WMIMethod -ComputerName $computer -Namespace root\ccm -Class SMS_CLIENT -Name TriggerSchedule "{00000000-0000-0000-0000-0000000000108}" | Out-Null)
All throw Not Found Errors.
Any ideas? Are these superseded?
{00000000-0000-0000-0000-000000000026} and {00000000-0000-0000-0000-000000000027} are user specfic and seem to have been changed to a different class that is sid dependent so that you can invoke it for any user. The most common example to call them is
$sched=([wmi]"root\ccm\Policy\$sid\ActualConfig:CCM_Scheduler_ScheduledMessage.ScheduledMessageID='{00000000-0000-0000-0000-000000000026}'")
$sched.Triggers=#('SimpleInterval;Minutes=1;MaxRandomDelayMinutes=0')
$sched.Put()
Where $sid is the users SID with each - replaced with a _
You can get them for logged on users like this:
$sids = (get-wmiobject -query "SELECT UserSID FROM CCM_UserLogonEvents WHERE LogoffTime = NULL" -namespace "ROOT\ccm").UserSID.replace('-','_')
However {00000000-0000-0000-0000-000000000113} and {00000000-0000-0000-0000-000000000108} should still work with the method you used. The only reason to throw the Not Found error for those is if they are not executed with elevated admin rights, but that is the same for all the other TriggerSchedule messages as well so I don't know what the problem could be.
I've been attempting to pass a variable in Powershell using Invoke-Command, however, every example I've found doesn't seem to work when using Get-CimInstance. This is the basic code I'm using is:
$Computer = (Read-Host "Enter Computer Name")
$User = (Read-Host "Enter User Name")
$Cred = (Get-Credential -Message "Enter Credentials" )
Invoke-Command -ComputerName $Computer -Credential $Cred -ScriptBlock {(Get-CimInstance -Class Win32_UserProfile -Filter 'LocalPath like "%$User"').LocalPath.split('\')[-1] | Remove-CimInstance}
When I run that I get a null value:
You cannot call a method on a null-valued expression.
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
+ PSComputerName : DBServer
I've also tried using the -ArgumentList flag, but that doesn't work either and I get the null value error again:
Invoke-Command -ComputerName $Computer -Credential $Cred -ScriptBlock {(Get-CimInstance -Class Win32_UserProfile -Filter 'LocalPath like "%$using:User"').LocalPath.split('\')[-1] | Remove-CimInstance} -ArgumentList $User
or:
Invoke-Command -ComputerName $Computer -Credential $Cred -ScriptBlock {(Get-CimInstance -Class Win32_UserProfile -Filter 'LocalPath like "%$args[0]"').LocalPath.split('\')[-1] | Remove-CimInstance} -ArgumentList $User
My best guess is that the -Filter flag is causing the issue. Though it works just fine if run locally. Also in my test case some usernames start with a dollar sign (ie $fredsmith) which may be an issue as well.
The doublequotes have to be on the outside to interpret the variable.
$user = 'joe'
"localpath like '%$user%'"
localpath like '%joe%'
This worked for me at an elevated prompt with the winrm service running:
invoke-command localhost {
get-wmiobject win32_userprofile -filter "localpath like '%$using:user%'" }
Or with no quoting issues:
invoke-command localhost {
get-ciminstance win32_userprofile | where localpath -match $using:user |
remove-ciminstance -whatif }
invoke-command localhost { param($user)
get-wmiobject win32_userprofile | where localpath -match $user } -args $user
invoke-command localhost {
get-wmiobject win32_userprofile | where localpath -match $args[0] } -args $user
i try to retrieve a list of Computer Names and their Current Operating System.
Everything works fine up to the point, where I have no Access with my Credentials on this certain server.
For explanation: For log into the servers i have to use another Account.
For every user ist CurrentUserName+"ad" (for ADministration)
The servers.txt is like
Server1
Server2
Server3
...
Let me show you 2 tries.
1.
$Login = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name +"ad"
$cred = Get-Credential $Login
$servers = get-Content .\server.txt
$OS = Get-WmiObject -class Win32_OperatingSystem -computername $servers -Credential $cred
$OS | Select-Object CSName, Caption, OSArchitecture | Export-CSV -path .\$(get-date -f yyyyMMd)_CurrentOS.csv
$OS | select CSName, Caption, OSArchitecture | Out-GridView -Title 'Current OS'
Everything is fine up to the point i add a Server where i have no logon rights.
After that i get the following error and NO server is succesfull.
Get-WmiObject : Zugriff verweigert (Ausnahme von HRESULT: 0x80070005 (E_ACCESSDENIED))
2.
$Login = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name +"ad"
$cred = Get-Credential $Login
$servers = get-Content .\server.txt
foreach ($server in $servers)
{
Try {
$OS = Get-WmiObject -class Win32_OperatingSystem -computername $server -Credential $cred -ea SilentlyContinue
} Catch {
Write-Host 'Logon Credentials not accepted. No access to'$Server'.' -fore white -back red
} Finally {
Write-Host 'Logon Credentials accepted. Grant access to'$Server'.'
}
}
$OS | Select-Object CSName, Caption, OSArchitecture | Export-CSV -path .\$(get-date -f yyyyMMd)_CurrentOS.csv
$OS | select CSName, Caption, OSArchitecture | Out-GridView -Title 'Current OS'
The output on the Screen is fine, except the "Out-GridView" Here is only the last Server shown in GridView.
Logon Credentials accepted. Grant access to DEBZIAPP104.
While adding this "bad server" i'll get
Logon Credentials accepted. Grant access to DEBZIAPP104.
Logon Credentials not accepted. No access to DEBZIAPP106.
Logon Credentials accepted. Grant access to DEBZIAPP106.
I want to list all servers that are fine. If there occurs a server where i have no logon rights, there should be shown a message and the script need to continue.
Please ask if anything is not clear.
Hope someone can help. :)
Greets,
Patrick
Try/Catch will only catch Terminating Errors.
This should set you straight:
$OS = Get-WmiObject -class Win32_OperatingSystem -computername $server -Credential $cred -ea Stop
As part of a backup operation, I am running the 7zip command to compress a folder into a single .7z file. No problems there as I am using the InVoke-WMIMethod.
Example:
$zip = "cmd /c $irFolder\7za.exe a $somedirectory.7z $somedirectory"
"InVoke-WmiMethod -class Win32_process -name Create -ArgumentList $zip -ComputerName $remotehost"
My problem comes in as my script continues, the 7za.exe process hasn't completed. I am then attempting to copy the item off of the remote system and it is either incomplete or fails.
Can someone point me in the direction to figure out how to identify if the 7za.exe process is still running, wait until it is dead, then proceed with the rest of my script?
I can grasp pulling the process from the remote system via...
get-wmiobject -class Win32_Process -ComputerName $remotehost | Where-Object $_.ProcessName -eq "7za.exe"}
Not sure how to turn that into usable info for my issue.
Answer UPDATE: (thx to nudge by #dugas)
This will do it with some feedback for those that need it...
do {(Write-Host "Waiting..."),(Start-Sleep -Seconds 5)}
until ((Get-WMIobject -Class Win32_process -Filter "Name='7za.exe'" -ComputerName $target | where {$_.Name -eq "7za.exe"}).ProcessID -eq $null)
You can invoke the Wait-Process cmdlet on the remote computer with the Invoke-Command cmdlet. Example:
$process = Invoke-WmiMethod -Class Win32_Process -Name create -ArgumentList notepad -ComputerName RemoteComputer
Invoke-Command -ComputerName RemoteComputer -ScriptBlock { param($processId) Wait-Process -ProcessId $processId } -ArgumentList $process.ProcessId
Since you mentioned using Invoke-Command is not an option, another option is polling.
Example:
$process = Invoke-WmiMethod -Class Win32_Process -Name create -ArgumentList notepad -ComputerName hgodasvccr01
$processId = $process.ProcessId
$runningCheck = { Get-WmiObject -Class Win32_Process -Filter "ProcessId='$processId'" -ComputerName hgodasvccr01 -ErrorAction SilentlyContinue | ? { ($_.ProcessName -eq 'notepad.exe') } }
while ($null -ne (& $runningCheck))
{
Start-Sleep -m 250
}
Write-Host "Process: $processId is not longer running"
You should be able to do it with a do... while loop that just sleeps until the process is finished.
do {
"waiting"
start-sleep 10
} while (gwmi -class win32_process -ComputerName $remotehost | Where ProcessName -eq "7za.exe")