Run Powershell Script on Multiple Remote Computers - powershell

Good day.
I apologize if this seems like a repetitive question but I the researches I have done have gotten me more confused. I'm trying to run the following Powershell script to delete a folder on some computers:
$users = get-childitem c:\users
foreach ($user in $users)
{
$folder = "C:\Users\" + $user + "\AppData\Local\Microsoft\OneDrive"
Remove-Item $folder -Recurse -Force -ErrorAction silentlycontinue
}
The script seems to work. How can I use this script on a list of remote computers?
Thank you.

You can utilize the Invoke-Command cmdlet with the ComputerName parameter. Example:
Invoke-Command { $env:ComputerName } -ComputerName SOMEMACHINE

As pointed out by dugas, you can use Invoke-Command to perform remote script execution using the -ScriptBlock and -ComputerName parameters.
# Create script block using surrounding {}
$sb = {
$users = Get-Childitem C:\Users -Directory -Name
foreach ($user in $users) {
$folder = "C:\Users\" + $user + "\AppData\Local\Microsoft\OneDrive"
Remove-Item $folder -Recurse -Force -ErrorAction silentlycontinue
}
}
# Create array of computer names since -ComputerName accepts an array
$computers = 'computer1','computer2','computer3'
Invoke-Command -ComputerName $computers -ScriptBlock $sb
There are numerous ways to traverse the remote directories. Using Get-ChildItem with -Directory and -Name parameters will return just the folder names under C:\Users.

Instead of having headache with offline computers, inaccwessible computers, etc, if you are using Active Directory domain, ask SysAdmin to create a Run-Once Scheduled Task using Group Policy Preferences.

Related

Using Powershell Get-ItemProperty through all of AD computers object

I'm a complete newbie in Powershell (and programming as you may have guessed), I want to get the result of the following PS command for each of our AD computer object and print the result in a text file...but I'm completely lost. Does anyone have a lifeline I could hold on to?
Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*" | Select-String -Pattern "mysoftwarename"
Thank you very much.
$ScriptBlock = {Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*" | Select-String -Pattern "mysoftwarename"}
$Computers = (Get-ADComputers -filter * ).name
$Creds = (Get-Credential)
foreach ($Computer in $Computers)
{
"`n`n$Computer`n" >> .\file.txt # "`n" just emulates Enter key press
Invoke-Command -ComputerName $Computer -ScriptBlock $ScriptBlock -Credential $Creds >> .\file.txt
}
This will work fine if you have all your computers online and PS remoting configured properly. Otherwise, it will require modifications.

How to find PST files on remote computers using Powershell script

I need some help. I cant’t find what’s wrong with my PowerShell script.
The goal is quite simple. I have to find (.*pst)-files on the users profile on domain computers in the network. Location to search is “C:\Users\”.
List of the PC names where exported to listcomputer.txt. The trouble is the script run with no errors and no message at all.
$computers = Get-Content c:\temp\listcomputer.txt
$filePath = "C:\Users\"
foreach($computer in $computers)
{
if(Test-Connection -ComputerName $computer -Quiet)
{
Invoke-Command -ComputerName $computer -ScriptBlock
{Get-ChildItem -Path $filePath -Recurse -Include '*.pst, *.ost'} }}
First of all I’ve to check connectivity to hosts by Test-Connection cmdlet.
Separately each of the command run successfully. I've tried it.
For example: Test-Connection -ComputerName $computer
runs with “true” result and it’s OK.
Also
Invoke-Command -ComputerName $computer -ScriptBlock {Get-ChildItem -Path $filePath -Recurse -Include '*.pst'} The result is displayed data with information about files were find in folders.
But all together run with no visible result in the PowerShell console console view result
Regards!
.pst can be located anywhere, even other drives, or attached storage. You are only looking for C:\.
So maybe this refactor to hit all potential connected drives.:
Get-Content -Path 'c:\temp\listcomputer.txt' |
ForEach-Object {
if(Test-Connection -ComputerName $PSItem -Quiet)
{
Invoke-Command -ComputerName $PSItem -ScriptBlock {
(Get-CimInstance -ClassName Win32_LogicalDisk).DeviceID |
ForEach-Object {
If ($PSItem -eq 'C:')
{Get-ChildItem -Path "$PSItem\Users" -Recurse -Include '*.pst, *.ost'}
Else {Get-ChildItem -Path $PSItem -Recurse -Include '*.pst, *.ost'}
}
}
}
}

Pass Varibles read from file to invoke-command

I'm struggling to remotely recycle all IIS app pools with powershell with the word "Test" in the name, but ALSO exclude a couple of specific AppPools with Test in the name. I can do it locally with:
## List of Apppool Names to Exclude
$Exclusions = Get-Content "C:\temp\Recycle TEST app pools Exclusions.txt"
## Load IIS module:
Import-Module WebAdministration
## Restart app pools with test in the name
Get-ChildItem –Path IIS:\AppPools -Exclude $Exclusions | WHERE { $_.Name -like "*test*" } | restart-WebAppPool}
However I can't get it to exclude the app pools from the list when I use:
$server = 'SERVER01', 'SERVER02'
## List of Apppool Names to Exclude
$Exclusions = Get-Content "C:\temp\Recycle TEST app pools Exclusions.txt"
## Load IIS module:
Import-Module WebAdministration
## Restart app pools with test in the name
invoke-command -computername $server -ScriptBlock {Get-ChildItem –Path IIS:\AppPools -Exclude $args[0] | WHERE { $_.Name -like "*test*" } | restart-WebAppPool}} -ArgumentList $Exclusions
The file "C:\temp\Recycle TEST app pools Exclusions.txt" does exist on the remote computer , but also does it need to? Can the list be passed in to the Invoke-Command also if it can be got to work?
Thanks in advance
While passing arrays as a single parameter can be difficult, you can take advantage of it here because you only have one argument type anyway.
invoke-command -computername $server -ScriptBlock {Get-ChildItem –Path IIS:\AppPools -Exclude $args[0] | WHERE { $_.Name -like "*test*" } | restart-WebAppPool}} -ArgumentList $Exclusions
In this, you use $args[0], but this is equivalent to $Exclusions[0] because all items in the array have been passed as arguments.
But if they've all been passed as arguments... that's what $args is. So use it exactly as you used $Exclusions locally.
Invoke-Command `
-ComputerName $server `
-ArgumentList $Exclusions `
-ScriptBlock {
Get-ChildItem –Path "IIS:\AppPools" -Exclude $args |
Where-Object Name -like "*test*" |
Restart-WebAppPool
}

Use PowerShell to remotely bulk override a file and restart a certain service

I need your help.
I need to write a script that will from a windows server,
Will connect to a list of servers (provided by a csv that has IP Addresses)
on those servers will overwrite a file located either on
C:\Program Files (x86)\Folder1 or C:\Program Files\Folder1
Taking the correct version from the server Running the script from D:\
and then restart a service called sname1.
(we can assume all target servers have the WinRM Active)
Your help will be greatly appriciated.
What I have so far is this, but I'm not sure it's correct assuming I'm working with IP Addresses and not Hostnames (Hostnames aren't an option as I'm not using this in a domain environment)
$servers=Get-Content D:\List.txt
foreach ($server in $servers)
{
if (Test-Path "\\$_\c$\Program Files\Folder1")
{
Copy-Item \\127.0.0.1\D$\file1.ini "\\$_\c$\Program Files\Folder1\file1.ini"
}
if (Test-Path "\\$_\c$\Program Files (x86)\Folder1")
{
Copy-Item \\127.0.0.1\D$\file1.ini "\\$_\c$\Program Files (x86)\Folder1\file1.ini"
}
Restart-Service -InputObject $(Get-Service -Computer $server -Name sname1)
}
REF:
$servers=Import-Csv E:\Temp\serverlist.csv
$Source = "D:\file1.ini"
foreach ($server in $servers)
{
$Password = ConvertTo-SecureString -AsPlainText -Force -String "$server.Password"
$User = "$server.Domain\$server.Usernaem"
$credentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $user,$password
if (Test-Path "\\$server.Alias\c$\Program Files\Folder1")
{
$Destination = "\\$server.Alias\c$\Program Files\Folder1"
}
if (Test-Path "\\$server.Alias\c$\Program Files (x86)\Folder1")
{
$Destination = "\\$server.Alias\c$\Program Files (x86)\Folder1"
}
Copy-Item $Source -Destination $Destination -Credential $credentials -Force
Restart-Service -InputObject $(Get-Service -Computer $server,Alias -Name sname1)
}
Note that you CANNOT access properties or methods of variables if you enclose it in quotes. For example, if you say;
$test = 1234
Write-Output "House $test.ToString()"
You will get the output "House 1234.ToString()" because the method is not resolved, it just assumes it's a string. You need to either split it up or enclose it:
Write-Output ("House " + $test.ToString())
Write-Output "House $($test.ToString())"
Additionally you've misspelled UserName when declaring $User. Fix those up and it should work fine.
I recommend checking out Microsoft's MVAs PowerShell 3.0 JumpStart and Advanced Tools & Scripting as they explain a lot of this stuff, get you into good habits and are actually pretty fun to watch.

Powershell Test-Path Not returning correct result

Hello if i run the following command I get a response of TRUE which is correct
Test-Path -Path "\\LT609247\c$\Users\*\AppData\Local\Microsoft\Outlook\*Internet Calendar*.pst"
However when I run the following commad in a script I get two FALSE returns. The iCalendar_Audit.csv contains two workstations one of which is LT609247.
$Computers = Get-Content c:\temp\iCalendar_Audit.csv
ForEach ($Computer in $Computers)
{ $ADComputer = $null
$ADComputer = Get-ADComputer $Computer
If ($ADComputer)
{
Add-Content c:\temp\iCalendar_Audit.log -Value "Found $Computer, checking for iCalendar"
Test-Path -Path "\\$ADComputer\c$\Users\*\AppData\Local\Microsoft\Outlook\*Internet Calendar*.pst"
}
}
$ADComputer will be an object, with several properties.. not a string with computer name. Assuming that $Computer is the computer name, you could either use $Computer like so -
Test-Path -Path "\\$Computer\c$\Users\*\AppData\Local\Microsoft\Outlook\*Internet Calendar*.pst"
Or, if $Computer is not the name of the computer, check the properties of $ADComputer object, in the interactive shell, and find the appropriate one, which is the name of the computer. (Could be $ADComputer.Name for example.