I'm trying to write a PowerShell script that will allow me to search for an old antivirus program on each computer in my domain, and if it has that program, run the Competitor Removal Tool that was given to us by our new AntiVirus software vendor. I also want the script to search for our new AV software, and if it's missing, install it. Both the Competitor Removal Tool and the .exe for the installer are stored on a Domain Controller and accessed via network share. I'm enabling PowerShell remoting in my organization, and I'm hoping that will give me more flexibility. Here's what I have so far:
#Retrieves list of all computers tied to Active Directory
$computers = Get-Content -Path 'C:\Sophos Results\ADComputers.txt'
#Paths to Sophos Installation and the Sophos Competitor Removal Tool
$SophosInstallPath = Get-ChildItem -File \\DC-02\netlogon\SophosInstall\Sophos-Installation.bat
$KasperskyRemove = Get-ChildItem -File \\DC-02\netlogon\SophosInstall\AVRemoveW.exe
#Loops through each AD Computer and tests for proper software installation
ForEach ($computer in $computers)
{
#Variables that store the path to 32-bit and 64-bit versions of Sophos
$Sophos64 = Test-Path "\\$computer\c$\Program Files\Sophos"
$Sophos32 = Test-Path "\\$computer\c$\Program Files (x86)\Sophos"
#Variables that store the path to 32-bit and 64-bit versions of Kaspersky
$Kaspersky64 = Test-Path "\\$computer\c$\Program Files\Kaspersky Lab"
$Kaspersky32 = Test-Path "\\$computer\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 $SophosInstallPath -Verbose
Write-Host "Beginning Sophos Installation on $computer"
}
#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 $KasperskyRemove -Verbose
Write-Host "Removing Kaspersky from $computer"
}
#The last block will only be executed if Sophos is installed and Kaspersky isn't, and makes no changes to the machine.
else {Write-Host "$computer has the proper AV software installation"}
}
At the moment, when I run this against a group of test computers, I don't get any errors, and I know that the script is correctly determining whether or not Kaspersky/Sophos is installed, but it won't launch the Competitor Removal Tool or the install file. I know once PowerShell remoting is enabled there will be a better way to do this, I'm just not sure what that way is. Any suggestions? Thanks in advance
Update:
I enabled PS Remoting on my local machine and tried the following:
Invoke-Command -ComputerName localhost -ScriptBlock { *Script from above* }
I got the following errors:
Access is denied
+ CategoryInfo : PermissionDenied: (\\dc-02\net...nstallation.bat:String) [Get-ChildItem], UnauthorizedAccessException
+ FullyQualifiedErrorId : ItemExistsUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
+ PSComputerName : localhost Cannot find path '\\dc-02\netlogon\SophosInstall\Sophos-Installation.bat' because it does not exist.
+ CategoryInfo : ObjectNotFound: (\\dc-02\net...nstallation.bat:String) [Get-ChildItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
+ PSComputerName : localhost Access is denied
+ CategoryInfo : PermissionDenied: (\\dc-02\net...l\AVRemoveW.exe:String) [Get-ChildItem], UnauthorizedAccessException
+ FullyQualifiedErrorId : ItemExistsUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
+ PSComputerName : localhost Cannot find path '\\dc-02\netlogon\SophosInstall\AVRemoveW.exe' because it does not exist.
+ CategoryInfo : ObjectNotFound: (\\dc-02\net...l\AVRemoveW.exe:String) [Get-ChildItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
+ PSComputerName : localhost Cannot validate argument on parameter 'FilePath'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
+ CategoryInfo : InvalidData: (:) [Start-Process], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.StartProcessCommand
+ PSComputerName : localhost
I'm running PowerShell from my domain admin account so I'm not sure why it would say access denied. Thanks for your help, I'm a bit new to both IT and PowerShell. Two months in on my first job
My last question: When I'm ready to do this on a larger scale, say my test group which has 3 computers (1 with Kaspersky, 1 With Sophos, and 1 with neither) The following should work, yes?:
$computers = Get-Content -Path 'C:\Sophos Results\TestGroup.txt'
Invoke-Command -ComputerName $computers -ScriptBlock { *Original Script here* }
Any preference between Invoke-Command and Enter-PSSession when dealing with multiple computers? In the description of Invoke-Command it says "To run a single command on a remote computer, use the ComputerName parameter. To run a series of related commands that share data, use the New-PSSession cmdlet" So if I do use Invoke-Command (which seems more straightforward to me) Should I save my script and then call it in the scriptblock? And then that leads me to wonder how I would call a script from my local machine on the remote machine? I apologize for so many questions, my head is just spinning the further I get down the rabbit hole here.
Update 7/19/2018:
Running into one more issue, hoping this is the last one. I copied the files from the remote server on to my local machine to get rid of the second hop problem. I will just copy the files from my local machine to all remote machines in the script. Problem is when I copy from local to remote, it only works when I specify the computer name like so :
Copy-Item -Path C:\Temp\AVInstall -Destination '\\Computer1\c$\Temp\AVInstall' -Recurse
If I try and use a computer variable, like below, I get a network path not found error:
Copy-Item -Path C:\Temp\AVInstall -Destination '\\$computer\c$\Temp\AVInstall' -Recurse
Any reason why that might be?