Using Powershell to test-path on a network drive - powershell

I can't get the Test-Path cmdlet to find a folder on a remote system's additional drive.
The following works for the system drive.
Test-Path -PATH '\\ServerName\C$\FolderName'
The next example always returns false.
Test-Path -PATH '\\ServerName\D$\FolderName'
I have verified the path and its spelling. Test-Path will find the path if I remote to the computer and run
Test-Path -PATH 'D:\FolderName'
I must be missing something. Will someone please enlighten me?

You need specified the UNC path in this way.
$path = 'filesystem::\\servername\D$\FolderName'
If(Test-path -Path $path){
Your code....
}
https://blogs.technet.microsoft.com/heyscriptingguy/2013/01/13/powertip-test-the-presence-of-a-remote-share-by-using-powershell/

Chances are the d-drive in this instance is not a logical disk on ServerName but a remote drive...
The Get-PSDrive CmdLet will return the details of the various drives available to your machine.
Get-PSDrive -PSProvider FileSystem will return, as you guessed it, file system drives! Pay particular attention to the Root property as this will show whether the drive in question is logical or remote.
You need to run this CmdLet when logged on the box, or alternatively you can use the Invoke-Command something like so:
Invoke-Command -ComputerName "ServerName" -Credential $(Get-Credential) -ScriptBlock {
Get-PSDrive -PSProvider FileSystem
}

You mention in one of the comments that it is a thumbdrive. Thumbdrives are not administratively shared by windows and therefore that share does not exist.
If you create a folder on the thumbdrive, such as d:\test and share that as "test", then you can test-path to "\servername\test" and get a good result.

Related

How do I reference the current logged in user when a script is running?

So, I'm using Desktop Central to run some scripts on a bunch of machines. The script is supposed to open a zip file in the c:\users%USERNAME%\ folder, and decompress it to a folder of my choosing. The idea is to use a single script for many machines, that can leverage the c:\users\LOGGEDONUSER\downloads folder (Default TEAMS download dir). The idea is that each user will download the archive from teams, and a script will decompress and install from each users DOWNLOADS folder.
The issue is that I don't seem to know how to write a script uses a variable representing the username of the logged in user for the -path in my argument.
For instance;
Extract file
Expand-archive -path $home\Downloads\SWANDPDM_SP5.1.zip -DestinationPath C:\temp\swpdminstaller\extracted\ -Force
#Define registry values to modify to allow for no UAC
$RegistryPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System'
$Name = 'ConsentPromptBehaviorAdmin'
$Value = '0'
#Run reg change
New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType DWORD -Force
#Run installer
Invoke-Item C:\temp\swpdminstaller\extracted\SOLIDWORKS_AND_PDM_2021_SP5.1\startswinstall.exe
#Define reg values to change back to default
$RegistryPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System'
$Name = 'ConsentPromptBehaviorAdmin'
$Value = '5'
#Run reg change
New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType DWORD -Force
This works great if I copy the script to the machine manually, and launch the script as a user. It looks at $home and figures out the correct directory based on whomever is logged in.
However, when it runs as Desktop Central, $home doesn't mean the same location. It comes back with this;
Expand-archive : The path 'C:\Windows\system32\config\systemprofile\Downloads\SWANDPDM_SP5.1.zip' either does not
exist or is not a valid file system path.
At C:\Program Files (x86)\DesktopCentral_Agent\Computer\startup\76507\SWandPDMdecomInstall.ps1:2 char:1
+ Expand-archive -path $home\Downloads\SWANDPDM_SP5.1.zip -DestinationP ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (C:\Windows\syst...NDPDM_SP5.1.zip:String) [Expand-Archive], InvalidOpe
rationException
+ FullyQualifiedErrorId : ArchiveCmdletPathNotFound,Expand-Archive
I tried using various env variables with no luck. It seems like because it's a "Desktop central" account that's running the script remotely, I can't get it to point to the correct folder in c:\users\NAMEOFLOGGEDINUSER\
So, it thinks $home = 'C:\Windows\system32\config\systemprofile\ instead of c:\users\NAMEOFLOGGEDINUSER\
Is there a way that I can get the username of the current logged on user, assign it to a variable, and then use that variable instead of $home? Keep in mind, it needs to find the logged in user while running the script as the Desktop Central service account. I've tried running the script as various domain admins\system accounts with no luck.
I thought about doing a whoami, writing to a text file, then omitting the domain portion of the output and assigning it to a variable, but there's got to be a better way.
Any help is greatly appreciated!
EDIT: Thought I was on to something, but it didn't work. I tried;
Expand-archive -path $env:HOMEPATH\Downloads\SWANDPDM_SP5.1.zip -DestinationPath C:\temp\swpdminstaller\extracted\ -Force
I see from the comments that you found a workaround. But to answer your original question, you can't get the logged in username from the usual Powershell techniques ($env:USERNAME, whoami, etc.) when you're running the script under a different security context.
But you can check who owns the Explorer.exe process:
$User = (Get-CimInstance Win32_Process -Filter "name = 'explorer.exe'" |
Invoke-CimMethod -MethodName GetOwner).User
The "Desktop central" user will probably not have Explorer running. However, if there are multiple users logged in via RDP sessions this will return an array.

Powershell Dynamic path location for files

I'm trying to make a script that installs apps etc. the script contains 7 ps1 scripts and they are linked together but when I move the folder the script won't work since the path changed is there a way so I can always have the right path?
& 'Z:\Windows installatie\Scripts\Menus\Apps.ps1'
this is when it's from a USB but the drive letter always changes.
I tried using a wild card but that didn't work.
& '*\Windows installatie\Scripts\Menus\Apps.ps1'
If you would like to test for the existence of a folder or file under an unknown drive letter, and you know the path is going to be unique enough, then you could just test for it by iterating through Get-PSDrive -PSProvider FileSystem.
$Drive = Get-PSDrive -PSProvider FileSystem | Where-Object { Test-Path ($_.Root + "path\to\myScript.ps1") }
if ($null -ne $Drive -and $Drive.Count -eq 1) {
& (Join-Path -Path $Drive.Root -ChildPath "path\to\myScript.ps1")
}
Not incredibly elegant, but will do the job.
If you know that you only have one USB mounted at a time, then you could also check for details about the drive that is a USB.

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

Powershell Invoke-Command Remove-Item Remote Server

I want to delete files on a particular folder of a remote server. I execute the following in Powershell:
Invoke-Command -Computer 'compname1' -ScriptBlock {Remove-Item -$args -force } -ArgumentList 'c:\BizTalkDeployment'
I get the following error:
Cannot find drive. A drive with the name '-c' does not exist.
c:\BizTalkDeployment is the correct path on server compname1.
Can anyone please explain what I've done wrong?
Remove the - in front of $args and re-run the script. You might even try changing the script block to:
Remove-Item -Path $args[0]
You could also remove the folder using a UNC path:
Remove-Item \\compname1\c$\BizTalkDeployment -force

open folder from Network with Powershell

I would like to open a txt.File from a sharedFolder with Powershell. The problem is, that it has to run whether an user is logged on or not. I'm looking for something like net-use.
The Program should also check, whether the psDrive exists or not.
Is it possible if I do that like this?
new-psdrive -name Z -psprovider FileSystem -root \\vcs.view
It works like that:
I map and then I check whether the file exists:
#mapping
try
{
new-psdrive -name Z -psprovider FileSystem -root $ShareFolder
}
catch
{
echo "WriteMessageTOAdmin ERROR!!"
exit
}
$folderPath = "Z:\users.txt"
if(!(test-Path -path $folderPath))
{
echo "WriteMessageTOAdmin ERROR!!"
exit
}
You don't need to map a network share to open a file on a network share:
Get-Content \\server\sharename\foo.txt
Works just fine as does using Test-Path on a UNC path e.g.
Test-Path \\server\sharename\foo.txt
Is there a reason you need to map the share to a local drive?