Powershell script searching files on domain - powershell

Very new to powershell and AD, so apologies if this post has an obvious answer. I have done some research and I am still not finding the answers I am looking for. My script is below for reference.
I have created a simple powershell script that will run on an admin vm i have setup on my domain. I have a separate SQL vm running a backup script that consume a lot of storage over time. I am trying to run this very simple script. My question is, do I need to modify this script in order to store it on my admin vm but have it run on my sql vm? Or can i leave the path as is and just set up in AD task scheduler. I have tried targeting the FQDN and the IP, but it doesn't seem to be working either way.
$backups_file = 'E:\blahBlahBla\SQL\Backups' or
$backups_file = '<IP_ADDRESS>\E:\blahBlahBla\SQL\Backups' or
$backups_file = '<FQDN>E:\blahBlahBla\SQL\Backups'
$backup_file_exist = (Test-Path -Path $backups_file)
if ($backup_file_exist){
# Verifies the folder exists
Write-Output -InputObject "This folder exists"
# returns all the files in the folder.
Get-ChildItem -Path $backups_file
# Deletes all files in the folder that are older that 7 days.
Get-ChildItem -Path $backups_file -Recurse | Where-Object {($_.LastWriteTime -lt (Get-
Date).AddDays(-7))} | Remove-Item
}
else
{
Write-Output -InputObject "Unable to access this directory."
}
Thanks.

well all your $backups_file solutions seems wrong to me.
If you want excess a directory on a Remote system, it has to be at least a fileshare or a administrative share like \\computer\e$\folder\folder\
But why using file shares or something like that when you just simple can connect to a Powershell Session on the Remote Host? here is a example.:
$mySQLServer = "Server1.domain.name", "server2.domain.name"
$backupFolder = "E:\blahBlahBla\SQL\Backups"
foreach ($server in $mySQLServer)
{
$session = New-PSSession -ComputerName $server #maybe -cred if needed
Invoke-Command -Session $session -ArgumentList $backupFolder -ScriptBlock {
param(
$directoy
)
if ($backup_file_exist)
{
# Verifies the folder exists
Write-Output -InputObject "This folder exists"
# returns all the files in the folder.
Get-ChildItem -Path $directoy
# Deletes all files in the folder that are older that 7 days.
Get-ChildItem -Path $directoy -Recurse | Where-Object { ($_.LastWriteTime -lt (Get-Date).AddDays(-7))
} | Remove-Item
}
}
Remove-PSSession
}
Good Luck!

Related

How to get the current script to read off computer names off a txt file located on c:\

I currently have this script working but only able to get it to run locally, I would like to have it read a text file that would be stored on c:\List_of_PCs.txt that would have computer names that it would also run the same script on. That way I can update the text file instead of modify the code.
Set-ExecutionPolicy RemoteSigned
# Get all users
$users = Get-ChildItem -Path "C:\Users"
# Loop through users and delete the Teams file
$users | ForEach-Object {
Remove-Item -Path "C:\Users\$($_.Name)\AppData\Roaming\Microsoft\Teams\Cache\f*" -Force
Remove-Item -Path "C:\Users\$($_.Name)\AppData\Roaming\Microsoft\Teams\Application Cache\Cache\f*" -Force
}
Any help on this I've tried multiple things every which way, I'm sure this is something simple but I'm still very new to PowerShell.
Try something like this...
Requires PowerShell remoting to be enabled and using an account that is an admin on the remote computer
$ComputerList = Import-Csv -Path 'c:\List_of_PCs.txt'
$ComputerList | % {
Invoke-Command -ComputerName $_ -ScriptBlock {
# Set-ExecutionPolicy RemoteSigned # this is something that should be set via GPO for all systems, not your script, so that it is centrally controlled and monitored.
# Get all users
$users = Get-ChildItem -Path "C:\Users"
# Loop through users and delete the Teams file
$users | ForEach-Object {
Remove-Item -Path "C:\Users\$($_.Name)\AppData\Roaming\Microsoft\Teams\Cache\f*" -Force
Remove-Item -Path "C:\Users\$($_.Name)\AppData\Roaming\Microsoft\Teams\Application Cache\Cache\f*" -Force
}
}
}

Confusion on Start-Job for File Share

So, this is absolutely whipping me. I have created a script that moves data based on a user's response to an number of questions from one file share to another. What I would like to do is have a background job running that provides a report of all the files being moved prior to the move taking place. As a result, I added this little bit of code that absolutely doesn't gather info from the source file share. It simply provides data from my particular machine. What am I doing wrong?
While ($sourcepath -eq $null) {
$sourcepath= read-host "Enter source file path"
}
Set-Location $sourcepath
Start-job -Scriptblock {Get-childitem -recurse |Out-File
c:\users\john.smith\desktop\shareonfile.txt}
Jobs run in a different process, with their own scope. The working directory won't be inherited. To demonstrate this:
Set-Location $sourcepath
Start-Job -ScriptBlock {
Get-Location
} | Wait-Job | Receive-Job
Get-Job | Remove-Job
You should avoid setting the location anyway, and just pass the path to Get-ChildItem. To do that in a job, define a parameter and pass its value like so:
Start-job -Scriptblock { param($thePath)
Get-childitem -Path $thePath -recurse |
Out-File c:\users\john.smith\desktop\shareonfile.txt
} -ArgumentList $sourcepath

Robocopy commands to copy a file to over 50 remote machines

I started looking at robocopy yesterday to try to copy and overwrite a file from one destination to many remote computers. I've tried Robocopy to copy files to a remote machine but it doesn't work. I get the same error as the person in the link. Does anybody have any suggestions or lead me in the right way ? thank you so much !
You could just use PowerShell for this. It has an inefficiency issue wherein it would copy one at a time but that shouldnt be an issue for 50ish machines. This could help if you made a PowerShell script
$computers = Get-Content "C:\filewithcomputers.txt"
$fileToCopy = "C:\filetocopy.txt"
ForEach($computer in $Computers){
Copy-Item -Path $fileToCopy -Destination "\\$computer\C`$\Temp"
}
The would copy the file $fileToCopy to each server in the file C:\filewithcomputers.txt assuming that the file contained a list of computer with each one on its own line. The file would be copied to the temp folder on each machine. Update the paths as required for your scenario. I only suggest this since you tagged powershell-remoting. If you are not adept with PowerShell maybe someone else can give you a better answer more of what you are looking for. Using RoboCopy for one file seemed tedious.
If you wanted to check to see if a folder exists and is accessible you could do something like this.
$computers = Get-Content "C:\filewithcomputers.txt"
$fileToCopy = "C:\filetocopy.txt"
ForEach($computer in $Computers){
$destinationx86 = "\\$computer\C`$\Program Files (x86)"
$destination = "\\$computer\C`$\Program Files"
If(Test-Path $destinationx86){
# Copy this to Program Files (x86)
Copy-Item -Path $fileToCopy -Destination $destinationx86
} Else {
# Copy this to Program Files
Copy-Item -Path $fileToCopy -Destination $destination
}
}
If you need to connect with different credentials, you can use
$credential = Get-Credential
New-PSDrive -Name "Computer01" -PSProvider FileSystem -Root "\\Computer01\Share" -Credential $credential -Scope global
Now you can copy to e.g. Computer01:\Folder01\
If you have set your environment up to support PSRemoting and have placed the file in a file share you can use PowerShell Remoting to instruct many computers to retrieve the file themselves nearly simultaneously with Invoke-Command. You can limit the number of simultaneous actions using -ThrottleLimit depending on the size of the source file and how robust the network/server are:
$computers = Get-Content "C:\filewithcomputers.txt"
$originalsource = "\\fileserver\shared\payload.exe"
$originaldestination = "c:\"
$scriptblockcontent = {
param($source,$destination)
Copy-Item -Path $source -Destination $destination
}
Invoke-Command –ComputerName $Computers –ScriptBlock $scriptblockcontent `
–ThrottleLimit 50 -ArgumentList $originalsource,$originaldestination

Uninstalling software on a remote client using powershell

I'm looking for a script that will help me uninstall a certain software on several clients in my network.
Right now i'm going through a list, access the client remotely, sign in with my administrator account and uninstalling the software before logging out and repeating the process. All of this is manually so i would like your help to write a powershell script that does these things for me.
Some Problems that might occur:
I can't log in remotely because i can't establish a connection to the client.
Another user might already be logged in on the client.
The software to be uninstalled is actually already uninstalled without my knowledge.
It's somewhere around 900 clients so a script would really help out.
Also, if it would be possible to, after the script is finished, to get a list of which clients that the software was uninstalled on and which clients it weren't would be great.
Questions written like this are likely to elicit 'What have you tried' type responses...
I would recommend using the Windows Installer Powershell Module Uninstall-MSIProduct.
I've described how to use this module remotely in this post: remote PCs using get-msiproductinfo, this example uses Get-MSIProductInfo but could be easily updated to use Uninstall-MSIProduct.
I've had a quick go at changing this to use Uninstall-MSIProduct, but haven't tested it.
[cmdletbinding()]
param
(
[parameter(Mandatory=$true,ValueFromPipeLine=$true,ValueFromPipelineByPropertyName=$true)]
[string]
$computerName,
[string]
$productCode
)
begin
{
write-verbose "Starting: $($MyInvocation.MyCommand)"
$scriptFolder = Split-Path -Parent $MyInvocation.MyCommand.Path
$moduleName = "MSI"
$modulePath = Join-Path -Path $scriptFolder -ChildPath $moduleName
$remoteScript = {
param($targetPath,$productCode)
Import-Module $targetPath
uninstall-msiproduct -ProductCode $productCode
}
$delayedDelete = {
param($path)
Remove-Item -Path $path -Force -Recurse
}
}
process
{
$remotePath = "\\$computerName\c$\temp\$moduleName"
write-verbose "Copying module to $remotePath"
Copy-Item -Path $modulePath -Destination $remotePath -Recurse -Container -Force
write-verbose "Getting installed products"
Invoke-Command -ComputerName $computerName -ScriptBlock $remoteScript -ArgumentList "c:\temp\$moduleName", $productCode
write-verbose "Starting job to delete $remotePath"
Start-Job -ScriptBlock $delayedDelete -ArgumentList $remotePath | Out-Null
}
end
{
write-verbose "Complete: $($MyInvocation.MyCommand)"
}

Call VBScript With Return Value on Remote Machine With Powershell

I need to call a remote VB script from Powershell, and the VB script needs to run on the remote machine.
I have been using \$computer\root\cimv2:Win32_Process").Create(C:\test.vbs)
This works, however I can't get a return value from the script, just a return value from the win32 process.
I would convert the whole thing to powershell, but can't as I'm connecting to a legacy domain I can't install additional tools on so have to call the remote vbscript
This is an old question but I would like to share my solution. It's the same as the one posted by Ansgar but it's been tested and working fine:
$VNC = '\\share\software\AppName\_Install_Silent.vbs'
$Computer = 'RemoteHost'
$TMP = "\\$Computer\c$\TEMP"
if (!(Test-Path $TMP)) {
New-Item -Path $TMP -ItemType Directory
}
Copy-Item -LiteralPath (Split-Path $VNC -Parent) -Destination $TMP -Container -Recurse -Force -Verbose
$LocalPath = Join-Path 'C:\TEMP' (Join-Path (Split-Path $VNC -Parent | Split-Path -Leaf) (Split-Path $VNC -Leaf))
Invoke-Command -ScriptBlock {cscript.exe $Using:LocalPath} -Computer $Computer
# Restart might be needed of remote host
The difference is that you have to copy the files first to the remote machine to avoid the double hop issue and then you can install it with the $Using variable.
Hope this helps someone.
I'd probably try either remote invocation:
Invoke-Command -ScriptBlock { cscript.exe "C:\test.vbs" } -Computer $computer
or PsExec:
PsExec \\$computer cscript.exe "C:\test.vbs"
Can't test either of them right now, though.