I created a script that runs from local pc and uses invoke-command to copy files from Host-1 to host-2.
the Relevant part:
$session =New-PSSession -Computername $Thost -Credential $mycreds
Invoke-Command -Session $session -ScriptBlock {
#seting a temp drive on Host for simple approch
Remove-PSDrive -Name w -Force
New-PSDrive -Name w -PSProvider FileSystem -Root $Using:VMPath -Credential $Using:mycreds -ErrorAction Stop
Write-Host "You Chose that $Using:OSVersion will be copyed to $Using:Thost"
Copy-Item -Path "w:\$Using:OSVersion" -Destination $using:VMXPath -Recurse
Remove-PSDrive -Name w -Force -ErrorAction Stop
}
first time I run the script it runs great!
First Run of the Script
the second time it says the PSdrive doesn't exist.
Second Run Error in PowerShell
after 10 min +- the script runs again with no issues
I'm surprised it runs the first time through. It looks like the failure is on the initial Remove-PSDrive. Its failing because you've already removed the w drive.
Adopt one of these 2 models
Remove-PSDrive -Name w -ErrorAction SilentlyContinue
New-PSDrive -Name w -PSProvider FileSystem -Root c:\test
Remove-PSDrive -Name w -Force
OR
if (Test-Path -Path w:\){
Remove-PSDrive -Name w -Force
}
New-PSDrive -Name w -PSProvider FileSystem -Root c:\test
Remove-PSDrive -Name w -Force
I'd go with the second option for preference
Related
Is there a way to disable Action Center Notifications in Windows 10 with PowerShell?
I found a way with 2 registry keys,
DisableNotificationCenter and ToastEnabled.
New-Item -Path "HKCU:\Software\Policies\Microsoft\Windows" -Name "Explorer" -force
New-ItemProperty -Path "HKCU:\Software\Policies\Microsoft\Windows\Explorer" -Name "DisableNotificationCenter" -PropertyType "DWord" -Value 1
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\PushNotifications" -Name "ToastEnabled" -PropertyType "DWord" -Value 0
This works with PowerShell 5 on Windows 10 EN, Version 21H2.
I have to translate a LINUX command into a Windows one. This is the command:
cat $(find folderName)/fileName
Searching online I found that:
cat can be translated with type
find can be translated with dir
So I tried to use something like this:
type #(dir folderName /s)/fileName
type < (dir folderName /s)/fileName
They are wrong, but I can't find any solution to combine them.
Can someone help me?
I am confident that others will provide FOR loop solutions.
This is not difficult if you use PowerShell Core or Windows PowerShell. If you are on a supported Windows system, Windows PowerShell was installed with it and is available.
While you might rightly say that this is more typing than needed in a bash/ksh script, it will run equally well on Linux, MacOS, and Windows without any modification. No 'translate' needed.
Get-Content -Path $(Get-ChildItem -Recurse -File -Path '.' -Filter 'sheet1.xml' |
Where-Object { $(Split-Path -Path $_.DirectoryName -Leaf) -eq 'worksheets' }).FullName
The amount of typing can be reduced by using aliases. While that is ok at an interactive shell, it is bad practice to encode aliases into script files.
gc $(gci -rec -file 'sheet1.xml'|?{$(Split-Path $_.DirectoryName -Leaf) -eq 'worksheets' }).FullName
If you are desperate to run this from a cmd command prompt, the following could be used.
powershell -NoLogo -NoProfile -Command ^
Get-Content -Path $(Get-ChildItem -Recurse -File -Path '.' -Filter 'sheet1.xml' ^| ^
Where-Object { $(Split-Path -Path $_.DirectoryName -Leaf) -eq 'worksheets' }).FullName
powershell -NoLogo -NoProfile -Command ^
gc $(gci -rec -file 'sheet1.xml'^|?{$(Split-Path $_.DirectoryName -Leaf) -eq 'worksheets' }).FullName
I am new to PowerShell and I need to write a script to start 3 or more windows services, in a specific order, with a set delay between them. I know how to write the script to start all of them, but I have no idea how to set the delay:
Get-Service -ComputerName cumputer_name -Name service_name1 | Stop-Service -Verbose
Get-Service -ComputerName cumputer_name -Name service_name2 | Stop-Service -Verbose
I believe you are looking for Start-Sleep.
Get-Service -ComputerName cumputer_name -Name service_name1 | Stop-Service -Verbose
Start-Sleep -Seconds 5
Get-Service -ComputerName cumputer_name -Name service_name2 | Stop-Service -Verbose
I'm learning Git Internals https://git-scm.com/book/en/v1/Git-Internals-Git-Objects
When I try to execute this command on Windows (using cmder a better console http://cmder.net/)
find .git/objects
I get an error
What should I do instead ?
find.exe in Windows is not the equivalent of find in linux.
The equivalent of find [startpath] in PowerShell would be:
Get-ChildItem [startpath] -Name
and in cmd.exe, it would be:
dir /B [startpath]
For an equivalent of:
find foo -type f
... I use:
Get-Children foo -Name -Recurse -File | % { $_ -replace "\\", "/" }
Use the FullName attribute, otherwise it will not show the full name if the path is long:
(Get-ChildItem -Path 'C:\dist\work' -Force -Recurse -ErrorAction 'SilentlyContinue' -Filter "objects").FullName
C:\dist\work\bam-client\.git\objects
C:\dist\work\bam-extras\.git\objects
:
I'm trying to copy all *.csproj.user files recursively from C:\Code\Trunk to C:\Code\F2.
For example:
C:\Code\Trunk\SomeProject\Blah\Blah.csproj.user
Would get copied to:
C:\Code\F2\SomeProject\Blah\Blah.csproj.user
My current attempt is:
Copy-Item C:\Code\Trunk -Filter *.csproj.user -Destination
C:\Code\F2 -Recurse -WhatIf
However I get:
What if: Performing operation "Copy Directory" on Target "Item:
C:\Code\Trunk Destination: C:\Code\F2\Trunk".
First, it wants to put them all in a new folder called F2\Trunk which is wrong. Second, it doesn't list any of the files. There should be about 10 files to be copied over.
What's the correct syntax for the command? Thanks!
Update:
Okay, it seems to have something to do with the fact that C:\Code\F2 already exists. If I try copying the files over to a destination that does not exist, it works.
I want to overwrite any existing .csproj.user files in the destination.
You guys are making this hideously complicated, when it's really simple:
Copy-Item C:\Code\Trunk -Filter *.csproj.user -Destination C:\Code\F2 -Recurse
Will copy the Directory, creating a "Trunk" directory in F2. If you want to avoid creating the top-level Trunk folder, you have to stop telling PowerShell to copy it:
Get-ChildItem C:\Code\Trunk | Copy-Item -Destination C:\Code\F2 -Recurse -filter *.csproj.user
While the most voted answer is perfectly valid for single file types, if you need to copy multiple file types there is a more useful functionality called robocopy exactly for this purpose with simpler usage
robocopy C:\Code\Trunk C:\Code\F2 *.cs *.xaml *.csproj *.appxmanifest /s
Seen this before, and I don't know why PowerShell can't seem to get it right (IMHO). What I would do is more cumbersome but it works.
$Source = 'C:\Code\Trunk'
$Files = '*.csproj.user'
$Dest = 'C:\Code\F2'
Get-ChildItem $Source -Filter $Files -Recurse | ForEach{
$Path = ($_.DirectoryName + "\") -Replace [Regex]::Escape($Source), $Dest
If(!(Test-Path $Path)){New-Item -ItemType Directory -Path $Path -Force | Out-Null
Copy-Item $_.FullName -Destination $Path -Force
}
I tried Jaykul answer and it did not work for me. I had to change it as below to get it to work. I also created the C:\Code\F2 folder before it worked.
Get-ChildItem C:\Code\Trunk -Recurse -filter *.csproj.user | Copy -Destination C:\Code\F2
Answer 1 looked good, and I changed to Move-Item for my purposes. However I found that in each folder it recursively went through, it only moved the first file. Below is my complete script which also includes some conversion of doc files to pdf's:
$Source = 'C:\Users\sgrody\Desktop\NSPM-Vol1'
$MoveFiles = '*.PDF'
$Dest = 'C:\Users\sgrody\Desktop\MedPassPDF'
$Folders = Get-ChildItem $Source -Directory -Recurse
ForEach ($Folder in $Folders)
{
$wdFormatPDF = 17
$word = New-Object -ComObject word.application
$word.visible = $false
$folderpath = "$($Folder.FullName)\*"
$fileTypes = "*.docx","*doc"
Get-ChildItem -path $folderpath -include $fileTypes |
foreach-object
{
$path = ($_.fullname).substring(0,($_.FullName).lastindexOf("."))
"Converting $path to pdf ..."
$doc = $word.documents.open($_.fullname)
$doc.saveas([ref] $path, [ref]$wdFormatPDF)
$doc.close()
}
$word.Quit()
}
Get-ChildItem $Source -Filter $MoveFiles -Recurse | ForEach{
$Path = ($_.DirectoryName + "\") -Replace [Regex]::Escape($Source), $Dest
If(!(Test-Path $Path)){New-Item -ItemType Directory -Path $Path -Force | Out-Null
Move-Item $_.FullName -Destination $Path -Force
}
}
Recently I had to replace a file present in several sub folders, I did it as below.
foreach($file in (Get-ChildItem File_you_want_to_be_copied.txt -Recurse)) {$target=$file.directoryname; Copy-Item -path C:\Source_Path\File_you_want_to_be_copied.txt -Destination $target}