Handle command for remote pc - windows

I want to run handle for a specific folder for a remote pc at my network so to know which processes are locking the folders.
tried:
handle /accepteula \\remotePcName\c:\myFolder
handle /accepteula \\remotePcName\User(name of the account)\c:\myFolder
and some other combinations with no luck getting
No matching handles found.
Is it possible to do this? Run handle for a remote pc?

Could you please try like this:
c:\powershell\Tools\psexec.exe \\remotePcName C:\handle.exe c:\myFolder

How about using invoke-command to execute 'handles' remotely?
$serverName = 'serverName'
$pathtoCheck = 'C:\temp' # folder you want to check on the remote server.
$pathtoHandle = 'c:\temp\handle.exe' #location of handle.exe on the remote server.
Invoke-command -ComputerName $serverName -Scriptblock {
param(
[string]$handles,
[string]$pathToCheck
)
"$handles /accepteula $pathToCheck" | Invoke-Expression
} -ArgumentList $pathtoHandle,$pathtoCheck

Related

How to check network folder exist with credentials using powershell 5

Lest say there is a network folder \\my_server\my_root\my_dir.
To access this folder these credentials required username: my_doman\my_user password: my_password.
Now in my program first it try to map network folder to a local drive. If there is a exception, it consider as folder not exist. I think this is not a good way.
Is there a way to check this folder exist without try to map to a local drive? I'm looking for something like
[System.IO.Path]::Exist("\\my_server\my_root\my_dir","my_doman\my_user","my_password")
I'm using Powershell 5
This is how I map the drive now
try{
$net = new-object -ComObject WScript.Network
$net.MapNetworkDrive($free_drive, $network_dir, $false, "domain\user", "password")
}catch{
Write-host: "folder does not exist"
}
Using New-PSDrive:
New-PSDrive -Name Q -PSProvider FileSystem -Root \\my_server\my_root\my_dir -Credential my_domain\my_user -Persist
Old School method using cmdline utility:
net use \\my_server\my_root\my_dir /user:my_domain\my_user my_password
start \\my_server\my_root\my_dir
For mapping you can use this:
$net = New-Object -comobject Wscript.Network
$net.MapNetworkDrive("Q:","\\my_server\my_root\my_dir",0,"my_domain\my_user","my_password")
For testing the path, you can use:
Test-Path \\my_server\my_root\my_dir
Note:You will get a boolean value in return from the test path.
Hope it helps.
Assuming that on the machine executing the script you're able to log in as the user under which you want to connect to the remote share, you could use Invoke-Command to invoke Test-Path as another user:
$pathExists = Invoke-Command -ComputerName . -Credential $credentials -ScriptBlock {
Test-Path -Path "\\my_server\my_root\my_dir"
}
if ($pathExists)
{
# my_dir\ exists
}
else
{
# my_dir\ is inaccessible/non-existent
}
I'm not in a position to test this at present but I suspect you may need to include -Authentication Credssp as a parameter to Invoke-Command (assuming the necessary environment for that is in place) due to the double-hop problem.
Of course, if you're checking for the existence of that directory under another user in order to make decisions for future filesystem operations to be executed as that same user, you would then need to Invoke-Command another batch of operations or include them after Test-Path. At that point you might be better off connecting to the share under alternate credentials in the usual way. It's just the difference between executing as another user and connecting as another user, each with their own pros and cons.
I was having the same problem checking the folder and/or file existence on a remote server before copying the file from deployment server. Nothing worked for me and ended up in a huge frustration.
I then tried this...
$pathExists = Invoke-Command -ComputerName <remoteServerName> -Credential $credentials
-ScriptBlock {
Test-Path -Path <AbsolutePath> "UNC path does not work here and you must use Absolute
path. eg. instead of \\Server use D:\Dir1 or D:\Dir1\File1.bat"
}
if (-not ($pathExists))
{
write-host "Directory or File does not exist"
}
else
{
write-host "Directory or File exist"
}
This worked just fine for me after using the absolute path in the Test-Path. For some reason the UNC path does not work! Hope, this helps someone!

Find if a program is installed on remote computer

I am trying to connect to remote computers with Active Directory and see if a single program is installed. I have tried a couple tutorials I found on the Internet, but with no success:
http://windowsitpro.com/powershell/what-applications-are-installed-computers-your-network
http://community.spiceworks.com/scripts/show/2170-get-a-list-of-installed-software-from-a-remote-computer-fast-as-lightning
I cannot get them to work properly, and they are not exactly what I am looking for.
An example of what I want to do: say I have 3 computers on my network:
123-abc
123-bcd
123-cde
and I want to see if the executable C:\Program Files (x86)\Mozilla Firefox\Firefox.exe exists. Can someone please explain how I can go about this in PowerShell?
The simplest way, provided you have domain admin privileges and administrative shares are enabled and accessible on the target computers, would be this:
$computers = '123-abc', '123-bcd', '123-cde'
$path = 'C$\Program Files (x86)\Mozilla Firefox\Firefox.exe'
$computers | % {
'{0}: {1}' -f $_, (Test-Path -LiteralPath "\\$_\$path")
}
There are a handful of ways to check for installed software. Some better suited than others. But if you're certain on the file path on each machine, the Test-Path CmdLet could be an easy approach.
Invoke-Command -ComputerName 123-abc -ScriptBlock {Test-Path 'C:\Program Files (x86)\Mozilla Firefox\Firefox.exe'}
You could probably throw that into a loop with a custom object so you can work with it as well.
For example, your code could look like this.
$pass = "password";
$secpass = ConvertTo-SecureString $pass -AsPlainText -Force;
$creds = New-Object System.Management.Automation.PSCredential("domain\login", $secpass);
Invoke-Command -ComputerName 123-abc, 123-bcd, 123-cde -Credential $creds -ScriptBlock {
Test-Path "C:\Program Files (x86)\Mozilla Firefox\Firefox.exe"
};
There are multiple ways of running powershell commands on remote computers.
Many commands support string[] parameter -ComputerName to which you can pass multiple computer names
You can use the Enter-PSSession cmdlet to enter a Telnet-like session on the remote machine
And finally, you can use the Invoke-Command cmdlet to run a script block against multiple remote hosts.

How can I launch .cmd files on a remote machine?

I need to be able to launch a .cmd file that is on a remote machine, from within the directory that the file resides on that machine.
I've tried: invoke-command -ComputerName test123 -ScriptBlock { cmd /c c:/myfile.cmd } in powershell, which launches the .cmd, but then fails because it can't find the corresponding .cmds that this one launches (which all reside in the same directory).
Is there a way to launch this .cmd file, and have it's execution persist? i.e., even after the powershell window is closed, the .cmd will continue to run on the remote machine.
You need to change the working directory in the scriptblock. Add a Set-Location before calling the batch script:
Invoke-Command -ComputerName test123 -ScriptBlock {
Set-Location 'C:\'
& cmd /c ".\myfile.cmd"
}
If you need to create a detached process, you can do that for instance via WMI:
$hostname = 'test123'
$command = 'C:\path\to\script.cmd'
$workdir = 'C:\working\directory'
$p = [wmiclass]"\\$hostname\root\cimv2:Win32_Process"
$p.Create($command, $workdir)
Note that you need admin privileges on the remote host for this.

PowerShell Invoke-Command performance issue

There are a few computers on my domain that I have access to remote into with PowerShell. I'm getting extremely slow performance when I remote into a particular computer with a command like this:
Invoke-Command -ComputerName someComputerName -ScriptBlock { ls C:\ } -credential myUsername
It takes about 10 seconds to display each file/folder on the drive. If I run the same command from within a session using Enter-PSSession then there are no performance issues. Also if I run a command like Get-Alias with Invoke-Command there are no performance issues. Lastly I can run any command on any other computer without any performance issues.
Any idea what could be causing this?
Thanks!
Could be a bandwidth issue. Does this run any faster?
convertfrom-csv (Invoke-Command -ComputerName someComputerName -ScriptBlock { ls C:\ | convertto-csv} -credential myUsername)

How to keep remote powershell command alive after session end?

I use the following command to run setup_server.exe on remote Windows box:
powershell -command "$encpass=convertto-securestring -asplaintext RPASSWORD -force;$cred = New-Object System.Management.Automation.PSCredential -ArgumentList RUSER,$encpass; invoke-command -computername RCOMPUTERNAME -scriptblock {setup_server.exe} -credential $cred;"
setup_server.exe's task is to create some configuration files and start my_server.exe (some daemon process), then it finishes. And I want my_server.exe to keep running after setup_server.exe is finished.
So when I do it via CMD on local box (i.e. just run setup_server.exe from CMD) it works, but when I do it via powershell on remote host it doesn't work. Namely the my_server.exe gets started, but right after setup_server.exe is closed the server also gets closed(killed).
So the question is following:
Which powershell flags/cmdlets should I use to make the described scenario to work as in local mode?
NOTE: I want synchronously get output of setup_server.exe, so running remote command with -AsJob flag, probably wouldn't work for me, though I even don't know if it will keep the server alive after setup_server.exe's end.
The way to keep the remote PowerShell session running after the command has finished is to use a PSSession e.g.:
$s = new-PSSession computername
Invoke-Command -session $s { ..script.. }
... do other stuff, remote powershell.exe continues to run
Remove-PSSession $s # when you're done with the remote session
Generally though exes should run independently from the app that launched them.
Why are you using Invoke-Command. If you want a persistent Session, use Enter-PSSession.
$s = New-PSSession -Computername "Computername";
Enter-PSSession -Session $s;
setup_server.exe
# Once you are finnished
Exit-PSSession
With 'Enter-PSSession' you are not just Invoking some Command on the Server, you are directly logged-in like you probably know from SSH.
If you want your powershell session to keep running because you are running an exe, try using the -InDisconnectedSession switch. From what I understand, it will run the executable on the remote machine in a session that isn't actually connected to your computer. In essence, your computer will not destroy the session, when it disconnects, allowing the exe to continue to run.
invoke-command -computername RCOMPUTERNAME -scriptblock {start-process setup_server.exe} -InDisconnectedSession
If you need to do this on multiple computers. Setup an array of all the computer names.
Note: I don't believe this works with sessions that are already created.
In order to keep a powershell code running on the session exit it should be a process. And the windows way to keep the process is running a .exe or a windows service.
To keep a Powershell shell open after executing a command, I use the -NoExit switch, e.g. this script starts a remote interactive PS session on servername with user administrator
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoExit
-Command "Enter-PSSession -ComputerName servername -Credential administrator"
http://powershell-guru.com/powershell-tip-13-prevent-powershell-from-exiting-once-script-finished/

Resources