0

I've been working on a script that will loop through a list of computers, uninstall old AV software if it's present and install our new AV software if it's not present. The script does this by executing two files: one is a batch script (called Sophos-Installation.bat) that will check for the presence of the old AV software, and run our new AV vendor's competitor removal tool. Once that is done the batch script will silently launch the executable to install our new AV software. The other file will only remove the old AV software, because I have some computers in my environment that have both. Here is the script:

#Variables that store the path to 32-bit and 64-bit versions of Sophos
$Sophos64 = Test-Path 'C:\Program Files\Sophos'
$Sophos32 = Test-Path 'C:\Program Files (x86)\Sophos'

#Variables that store the path to 32-bit and 64-bit versions of Kaspersky
$Kaspersky64 = Test-Path 'C:\Program Files\Kaspersky Lab'
$Kaspersky32 = Test-Path 'C:\Program Files (x86)\Kaspersky Lab'

#The following block will run the Sophos-Installation batch file, removing any instance of Kaspersky and installing Sophos
      If ($Sophos64 -eq $false -or $Sophos32 -eq $false) 
      {
      Start-Process -FilePath C:\Temp\AVInstall\Sophos-Installation.bat
      $env:COMPUTERNAME |Out-File -FilePath "\\CCIT-4BXZPN2LP\c$\Sophos Results\Sophos_Installed.txt" -Append
      }
#The following block will remove Kaspersky from a machine if it is present and Sophos is already installed.
        Elseif (($Kaspersky64 -eq $true -or $Kaspersky32 -eq $true) -and ($Sophos64 -eq $true -or $Sophos32 -eq $true)) 
        {
        Start-Process -FilePath C:\Temp\AVInstall\AVRemoveW.exe
        $env:COMPUTERNAME | Out-File -FilePath "\\CCIT-4BXZPN2LP\c$\Sophos Results\Kaspersky_Removed.txt" -Append
        }
#The last block will only be executed if Sophos is installed and Kaspersky isn't, and makes no changes to the machine.
        else {$env:COMPUTERNAME | Out-File -FilePath "\\CCIT-4BXZPN2LP\c$\Sophos Results\Proper_Configuration.txt" -Append}

And I have another script that I've been running that copies the necessary files to the remote computer before launching the above script and logging the computer name in a file to my PC. (unsuccessfully right now. I get an access denied error when the script tries to write to the .txt files. I'm less concerned about that right now but if someone wants to take a whack at that as well feel free.) Here is that script:

    $computers = Get-Content -Path 'C:\Sophos Results\TestGroup.txt'
ForEach ($computer in $computers)
{
$connection = Test-Connection -ComputerName $computer -Quiet
if ($connection = $true)
{
try{
Copy-Item -Path C:\Temp\AVInstall -Destination "\\$computer\c$\Temp\AVInstall" -Recurse -Force
Invoke-Command -ComputerName $computer -FilePath 'C:\Sophos Results\InstallSophos_UninstallKaspersky_Test.ps1'
echo $computer | Out-File 'C:\Sophos Results\Script_Successful.txt' -Append
}
catch {
echo $computer | Out-File -FilePath 'C:\Sophos Results\Script_Failed.txt' -Append
}
}
else {echo $computer | Out-File -FilePath 'C:\Sophos Results\UnreachableComputers.txt'}
}

When running this script, the files copy over properly, the batch file executes (the batch file also creates a log on the remote machine when it is run, so I know it's executing) but the old AV isn't uninstalled and the new AV isn't installed. When I remoted into one of my test computers, I manually ran the Sophos-Installation.bat file and got the following error:

Access is denied. Access is denied. The username or password is incorrect.

I was then prompted for my admin credentials, and then the batch file worked as intended. So clearly I need to pass my admin credentials to these machines in order to get this to work. Every other time I've tried to pass credentials in PowerShell it hasn't worked properly so I'm hoping someone on here can tell me the following:

  • How do I setup a credential variable that will work
  • Where in the above scripts do I need to implement that credential variable.
  • Any other information I might need to know to get this working properly.

Please keep in mind when answering that I'm a beginner in PowerShell (and IT in general, this is my first IT job), I took a class about 6 weeks ago and this is my first project that will implement it. Thanks in advance for your help!

Update: I've added a credential variable to my script. I've implemented it in 3 places and I'm still getting prompted for credentials on my end. Here are my updated scripts:

#Variables that store the path to 32-bit and 64-bit versions of Sophos
$Sophos64 = Test-Path 'C:\Program Files\Sophos'
$Sophos32 = Test-Path 'C:\Program Files (x86)\Sophos'

#Variables that store the path to 32-bit and 64-bit versions of Kaspersky
$Kaspersky64 = Test-Path 'C:\Program Files\Kaspersky Lab'
$Kaspersky32 = Test-Path 'C:\Program Files (x86)\Kaspersky Lab'

#The following block will run the CCOB-Sophos-Installation batch file, removing any instance of Kaspersky and installing Sophos
      If ($Sophos64 -eq $false -or $Sophos32 -eq $false) 
      {
      Start-Process -FilePath C:\Temp\AVInstall\CCOB-Sophos-Installation.bat -Credential $cred 
      $env:COMPUTERNAME |Out-File -FilePath "\\CCIT-4BXZPN2LP\c$\Sophos Results\Sophos_Installed.txt" -Append
      }
#The following block will remove Kaspersky from a machine if it is present and Sophos is already installed.
        Elseif (($Kaspersky64 -eq $true -or $Kaspersky32 -eq $true) -and ($Sophos64 -eq $true -or $Sophos32 -eq $true)) 
        {
        Start-Process -FilePath C:\Temp\AVInstall\AVRemoveW.exe -Credential $cred
        $env:COMPUTERNAME | Out-File -FilePath "\\CCIT-4BXZPN2LP\c$\Sophos Results\Kaspersky_Removed.txt" -Append
        }
#The last block will only be executed if Sophos is installed and Kaspersky isn't, and makes no changes to the machine.
        else {$env:COMPUTERNAME | Out-File -FilePath "\\CCIT-4BXZPN2LP\c$\Sophos Results\Proper_Configuration.txt" -Append}

and:

    #credentials
$username = "mydomain\myusername"
$password = Get-Content -Path 'C:\Sophos Results\mysecurestring.txt' | ConvertTo-SecureString
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $password

    $computers = Get-Content -Path 'C:\Sophos Results\TestGroup.txt'
    ForEach ($computer in $computers)
    {
    $connection = Test-Connection -ComputerName $computer -Quiet
    if ($connection -eq $true)
    {
    try{
    Copy-Item -Path C:\Temp\AVInstall -Destination "\\$computer\c$\Temp\AVInstall" -Recurse -Force 
    Invoke-Command -ComputerName $computer -FilePath 'C:\Sophos Results\InstallSophos_UninstallKaspersky_Test.ps1' -Credential $cred
    echo $computer | Out-File 'C:\Sophos Results\Script_Successful.txt' -Append
    }
    catch {
    echo $computer | Out-File -FilePath 'C:\Sophos Results\Script_Failed.txt' -Append
    }
    }
    else {echo $computer | Out-File -FilePath 'C:\Sophos Results\UnreachableComputers.txt'}
    }

While the command to create the secure string file isn't in the script I did create it. I've used the credential parameter with Invoke-Command, and the two Start-Process commands, but I'm still being prompted for a username and password.

Community
  • 1
  • 1
Sweet T
  • 5
  • 1
  • 5
  • 1
    As a best practice, don't compare bools. It's overly verbose and can be more succinctly stated: `!$bool` or `-not $bool` – Maximilian Burszley Jul 23 '18 at 18:53
  • 1
    Another issue in the second code block is that `if ($connection = $true)` is _assigning_ the value `$true` to `$connection`, not performing a comparison. I.e., that statement block will **always** run. To _evaluate a condition_, should be `if ($connection -eq $true)`. – kuujinbo Jul 23 '18 at 19:09
  • 1
    Possible duplicate of [Powershell - Run a script located at a remote machine which inturn access files from a network share](https://stackoverflow.com/questions/4596053/powershell-run-a-script-located-at-a-remote-machine-which-inturn-access-files) and https://stackoverflow.com/q/2233758/, https://stackoverflow.com/q/47316715/, https://stackoverflow.com/q/30122793/, https://stackoverflow.com/q/19660891/, https://stackoverflow.com/q/7794206/ – TessellatingHeckler Jul 23 '18 at 19:16
  • @TheIncorrigible1 can you expand on that? What would I be replacing in my script? Thanks! – Sweet T Jul 24 '18 at 14:08
  • @kuujinbo you're right, I overlooked that. Thanks for catching it. – Sweet T Jul 24 '18 at 14:08
  • @SweetT You're comparing bools (`$var -eq $false`). This is unnecessary, overly verbose, and a bad practice in any programming language. You should use a logic switch (`!$var` or `-not $var`) and in case of `true`: `if ($var) {`. They're explicitly `true` or `false` already. A good practice for `bool` variables is to name them as a question, like: `$IsSophos32Installed` – Maximilian Burszley Jul 24 '18 at 14:11
  • Have you tried passing credentials as outlined here: https://stackoverflow.com/q/6239647/604196.[More examples can be found here](https://social.technet.microsoft.com/wiki/contents/articles/4546.working-with-passwords-secure-strings-and-credentials-in-windows-powershell.aspx). – kuujinbo Jul 24 '18 at 15:49

1 Answers1

0

Can you please test the below code I have added a credential

$Username = "administrator"
 $Password  = ConvertTo-SecureString 'Administrator password here' -AsPlainText -Force

     $Credentials  = New-Object System.Management.Automation.PSCredential $Username, $Password

    $computers = Get-Content -Path 'C:\Sophos Results\TestGroup.txt'
    ForEach ($computer in $computers)
    {
    $connection = Test-Connection -ComputerName $computer -Quiet
    if ($connection = $true)
    {
    try{
    Copy-Item -Path C:\Temp\AVInstall -Destination "\\$computer\c$\Temp\AVInstall" -Recurse -Force -Credential $Credentials
    Invoke-Command -ComputerName $computer -FilePath 'C:\Sophos Results\InstallSophos_UninstallKaspersky_Test.ps1' -Credential $Credentials
    echo $computer | Out-File 'C:\Sophos Results\Script_Successful.txt' -Append
    }
    catch {
    echo $computer | Out-File -FilePath 'C:\Sophos Results\Script_Failed.txt' -Append
    }
    }
    else {echo $computer | Out-File -FilePath 'C:\Sophos Results\UnreachableComputers.txt'}
    } 
justintjacob
  • 193
  • 1
  • 6