Invoke-Command in a foreach

Welcome Forums General PowerShell Q&A Invoke-Command in a foreach

This topic contains 2 replies, has 2 voices, and was last updated by

 
Participant
1 week, 2 days ago.

  • Author
    Posts
  • #158066

    Participant
    Topics: 2
    Replies: 2
    Points: 14
    Rank: Member

    Hello friends,

    I'm still a Powershell rookie and to step up my scripting I'm working on a script that check the version of all servers in the list, copy a patch file to the server and then execute wusa.exe to install the patch. I do have access rights on the server and share and I'm able to to copy the file if I just run it as a oneliner.

    If I'm running the script I get the following error:

    Access is denied
    + CategoryInfo : PermissionDenied: (\\server\share\...4499164-x64.msu:String) [Copy-Item], UnauthorizedAccessException
    + FullyQualifiedErrorId : ItemExistsUnauthorizedAccessError,Microsoft.PowerShell.Commands.CopyItemCommand
    + PSComputerName : WEB

    $Serverlist = "WEB1", "WEB2"
    
    foreach($Server in $Serverlist){
    
    < # 
    $RemoteServerIntallPath = "\\$Server\C$\Temp\Patches"
    
    IF (Test-Connection -ComputerName $Server -Count 1 -Quiet){
    Write-Host "Ping $Server"
    
    IF(!(Get-HotFix -ComputerName $Server -Id "KB4499149" -InformationAction SilentlyContinue)){
    Write-Host "Hotfix needed of $server!"
    
    IF(!(Test-Path $RemoteServerIntallPath)){
    New-Item -Path $RemoteServerIntallPath -ItemType Directory | Out-Null
    Write-Host "Directory created: $RemoteServerIntallPath"
    }else{
    Write-Host "Folder exists on $Server!"
    }
    }
    }
    #>
    
    Invoke-Command -ComputerName $Server -ScriptBlock {
    $RemoteServerIntallPath = "\\$env:COMPUTERNAME\C$\Temp\Patches"
    $WinSRV2008R2 = "\\Server\share\windows6.1-kb4499164-x64.msu"
    $WinSRV2008SP2 = "\\Server\share\windows6.0-kb4499149-x64.msu"
    $OSVersion = Get-CimInstance -ClassName Win32_OperatingSystem -Property Version
    #$Cred = Get-Credential
    
    IF($OSVersion.Version -like "6.1.*"){
    Copy-Item -Path $WinSRV2008R2 -Destination $RemoteServerIntallPath -Verbose #-Credential $Cred
    #Copy-Item -Path "\\Server\share\windows6.1-kb4499164-x64.msu" -Destination $RemoteServerIntallPath
    Write-Host "Kopied file to $env:COMPUTERNAME"
    Start-Process 'wusa.exe' -ArgumentList 'C:\Temp\patches\kb4103712.msu', '/quiet', '/norestart'
    
    }elseif($OSVersion.Version -like "6.0.*"){
            Write-Host "$Server is a Windows Server 2008 SP2"
    }else{
    Write-Host "$Server is not a Windows Server 2008 SP2 or 2008 R2"
    }
    }
    }

     

  • #158202

    Participant
    Topics: 2
    Replies: 957
    Points: 1,730
    Helping Hand
    Rank: Community Hero

    You may have permissions to the server and the share, but unless the PowerShell session you are running, is running as a account on the targets that is in the local administrators group, your command will fail.

    With the exception of only a handful of cmdlets, you must be in the target host local admin group for PSRemoting to work.

    Also, why not just copy to installer to the RunOnce location, and restart the system, vs trying to run this installer remotely?

    • #159960

      Participant
      Topics: 2
      Replies: 2
      Points: 14
      Rank: Member

      Hi Postanote,

      Thanks for your reply and sorry for the late reply.

      I found another soloution with PsExec.

      https://community.spiceworks.com/topic/2054098-silently-install-patches-remotely-and-reboot

      $RootHotfixPath = '\\Server\Rollup\2008 R2\'
      
      $Hotfixes = @('windows6.1-kb4499164-x64.msu')
      $Servers = "WEB"
      
      foreach ($Server in $Servers)
      {
      Write-Host "Processing $Server..."
      
      $needsReboot = $False
      $remotePath = "\\$Server\c$\Temp\Patches\"
      
      if( ! (Test-Connection $Server -Count 1 -Quiet)) 
      {
      Write-Warning "$Server is not accessible"
      continue
      }
      
      if(!(Test-Path $remotePath))
      {
      New-Item -ItemType Directory -Force -Path $remotePath | Out-Null
      }
      
      foreach ($Hotfix in $Hotfixes)
      {
      Write-Host "`thotfix: $Hotfix"
      $HotfixPath = "$RootHotfixPath$Hotfix"
      
      Copy-Item $Hotfixpath $remotePath
      # Run command as SYSTEM via PsExec (-s switch)
      & "C:\Program Files (x86)\SysinternalsSuite\PsExec" -s \\$Server wusa C:\Temp\Patches\$Hotfix /quiet /norestart
      write-host "& C:\Windows\PsExec -s \\$Server wusa C:\Temp\Patches\$Hotfix /quiet /norestart"
      if ($LastExitCode -eq 3010) {
      $needsReboot = $true
      }
      }
      
      # Delete local copy of update packages
      Remove-Item $remotePath -Force -Recurse
      
      if($needsReboot)
      {
      Write-Host "Restarting $Server..."
      Restart-Computer -ComputerName $Server -Force -Confirm
      }
      }

You must be logged in to reply to this topic.