I want to execute a few lines of code on every Server (160+).
For this I decided to get my Serverlist via Powercli and pass this list to Enter-PSSession.
...
Connect-VIServer -Server $VIServer -Credential $creds
$servers = Get-VM |select Name |where Name -Like "SV*"
...
foreach($server in $servers)
{
try{
Enter-PSSession -ComputerName $server -Credential $cred -ErrorAction Stop
Get-NetIPAddress |where AddressFamily -EQ 2 |where InterfaceAlias -Like "Ethernet" |select IPAddress
Exit-PSSession
}catch{
Write-Host "Error on $server"
}
}
the problem seems to be, that it takes an array as the ouput error is following
Error on #{Name=<$server>}
But I dont know how to handle this correctly
Use New-Pssession or Invoke-command for remoting. Enter-Pssession is interactive and the way you are doing it, the get-netipaddress is running on your local machine and not on your remote machine.
Use $servers.Name instead of $servers in your foreach loop.
foreach($server in $servers.Name) #This .name should fix your problem
{
try{
New-PSSession -ComputerName $server -Credential $cred -ErrorAction Stop -Name MySession
Invoke-Command -Session $MySession -ScriptBlock {Get-NetIPAddress |where AddressFamily -EQ 2 |where InterfaceAlias -Like "Ethernet" |select IPAddress}
Remove-PSSession
}catch{
Write-Host "Error on $server"
}
}
Related
I am trying to fetch IIS status from remote server using powershell.
I have used command Get-Service but i don't recieve any output from this command.
Below is my code block.
$pass='pass'|ConvertTo-SecureString -AsPlainText -Force;
$Credentials = New-Object
System.Management.Automation.PsCredential("user",$pass);
$Service=invoke-command -computername "server" -credential $Credentials -
scriptblock {Get-Service|Where-Object Name -eq 'IISADMIN'}
if($Service.Status -eq 'Running')
{
write-host "IIS Running"
}
else
{
throw "IIS not running or Not installed"
}
I Checked your code and did not see any problem with it, Did you checked the service exists locally using Get-Service or Service Manager?
Anyway you don't have to use Invoke-Command for this, you can use the built in -ComputerName parameter of the Get-Service cmdlet,
And if you need to provide credentials, you can use WMI:
$Credential = New-Object System.Management.Automation.PsCredential($username, $encrypted)
$Service = Get-WmiObject -Class win32_service -ComputerName Server -Filter 'Name = "W3SVC"' -Credential $Credentials
Try using a WMI call instead, I have found it far more reliable when working with remote servers.
$Service = Get-WmiObject -Computername $computer -Credential $credentials Win32_service -ErrorAction Continue | Where {$_.Name -eq 'IISADMIN'}
Not exactly sure why I am getting this error - input object cannot be bound to any parameters for the command either because the commmand does not take pipeline input and its properties do not match any of the parameters that take pipeline input. Any assistance is appreciated
Code snippet below
$Session = New-PSSession -ComputerName DC1 -Credential $Cred
Import-Module ActiveDirectory -PSSession $Session
$comp = $env:COMPUTERNAME
if ($ComputerName -eq $null) {
Invoke-Command -Session $session -ScriptBlock {$using:PC
}
if($comp.substring(5,3) -imatch "Dbs"){
Get-ADObject $PC |
Move-ADObject -Targetpath "ou=Database,
dc=com,dc=company,dc=net"
Write-Host "Moved to Datbases"}
}
Remove-PSSession -Session $Session
Have you tried getting the object explicitly?
$Session = New-PSSession -ComputerName DC01 -Credential $Cred
Import-Module ActiveDirectory -PSSession $Session
$comp = $env:COMPUTERNAME
if($comp.substring(5,3) -imatch "Sys")
{
$adObject = Get-ADObject -Filter {Name -eq $comp}
Move-ADObject -Identity $adObject -Targetpath "ou=System Servers,ou=PRD,ou=Servers,dc=com,dc=myCompany,dc=net"
}
elseif($comp.substring(5,3) -imatch "App")
{
You are both piping in the output of Get-ADComputer and also defining the -Identity property which are conflicting. Chose one way or the other.
Get-ADComputer $comp | Move-ADObject -Targetpath "ou=Database, dc=com,dc=company,dc=net"
or
$ADComputer = Get-ADComputer $comp
Move-ADObject -Identity $ADComputer -Targetpath "ou=Database, dc=com,dc=company,dc=net"
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")
I am new to Powershell Scripting. I what I am trying to accomplish is to write a script that will query WMI for KMS Licence status on just the KMS channel and the CMID of the machine I would like the output to be put into excel. Also The script I am writing pops up with a access denied error on a few machines that I am unable to suppress. any help would be appreciated.
$AllADComputers = Get-ADComputer -searchbase "OU=CC3DELLS,DC=Sample,DC=com"
ForEach ($Computers in $AllADComputers)
{
$ComputerName = $Computers.Name
if ((Test-Connection -computername $ComputerName -Quiet -ErrorAction SilentlyContinue) -eq $true) {
$ComputerCMID = Get-WmiObject –computer $ComputerName -class SoftwareLicensingService -ErrorVariable err -ErrorAction SilentlyContinue -WarningAction SilentlyContinue -Credential $Cred | Select-object ClientMachineID -ErrorAction SilentlyContinue
Write-host "$ComputerName has the $ComputerCMID "
} else {
Write-Host "$ComputerName is Down" -ForegroundColor Red
}}
The following worked for me:
$ErrorActionPreference = "SilentlyContinue"
$ComputerCMID = Get-WmiObject –computer $ComputerName -class SoftwareLicensingService
$ErrorActionPreference = "Continue"
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")