Powershell: How to copy a file from TFS to a different destination - powershell

I'm writing a powershell script for deployment. I need to copy changed files from TFS to our Test Server. I have been able to retrieve the change sets, and I have been able to drill down to the Item. I have access to the path of the source file.
Does anyone know an efficiect way of doing this? Do I need to use the DownloadFile cmdlet or can I just use the Copy-Item cmdlet.
path of sourcefile is $file.ServerItem which resolves to, for example, $/Project/PromonetBaseline/Main/Source/ItemHierarchy.vb
Destination is a path like \\104Server\WebApps\PromonetBaseline\Main\Source\ItemHierarchy.vb
Is there a neat way to do this programatically?
Any input is appreciated.
Thanks,
Akin

For something like this, I would set up a local workfold mapping for the source files, get those files and then use Copy-Item to copy the source files to the destination folder. You can use the -Force parameter on Copy-Item to overwrite an existing file.
Another option is to use tf view itemspec /i > tempfilename to get the files from the server without creating a local workfold mapping.

Related

Using xcopy instead of robocopy for wildcarded files

I'm working on an old 2003 server and I want to copy a folder for specific files while also retaining the folder structure.
Note: I am not allowed to install or add robocopy onto this server.
The command that I use on another server is usually something like this.
robocopy Application Application_small *.txt /E
This, of course, gives me a new directory with nothing but the .txt files and the same folder structure.
But of course, robocopy isn't on Server 2003. However, xcopy does exist. Is there an equivalent switch that I can use to get the same kind of result as robocopy?
Similar question was found here.
xcopy Application\*.txt Application_small /s

What is PowerShell command output default location?

Following this official Azure tutorial. When I run the following PowerShell command (mentioned in Create a project ZIP file section of the tutorial), it runs successfully but I don't know where the zip file created by the command is located.
Compress-Archive -Path * -DestinationPath myAppFiles.zip
I don't see the file in following location either: C:\Windows\System32\WindowsPowerShell\v1.0. What is the default output location for PS command?
The default output location in this case is your current working directory. Running that cmdlet as posted will copy everything in the current directory into $CurrentDirectory\myAppfiles.zip
Note that as you're not specifying the actual path, you'll want to Set-Location to the actual location of the items you're trying to compress. When you do that, the .zip file will end up in that directory.

How to load my custom PowerShell module? [duplicate]

I have to create a PowerShell script which does exactly same thing as my previous script, but this time I have to read a CSV file instead of an XML file. My plan is to create a PowerShell script which has common functions required for both scripts and re-use this common script file in both main files.
Suppose I create 2 main files in 2 directories in C:\ drive and keep my common file and other 3rd party libraries in a folder of D:\ drive, e.g. C:\script_1_folder\Script1.ps1, C:\script_2_folder\Script2.ps1 and common file and 3rd party libraries will be in D:\script_common.
How do I call\re-use common file in my main files (how to get the path, do I have to create an instance of common file and how do I use it)
What is the difference between
$script_path = $myinvocation.invocationname;
$script_folder = split-path $script_path -parent;
write-host $script_folder
$script_name = split-path $script_path -leaf;
$current_folder = [system.io.directory]::getcurrentdirectory()
[system.io.directory]::setcurrentdirectory($script_folder)
Set-Location $script_folder
add-type -path ".\AlexFTPS-1.1.0\AlexPilotti.FTPS.Client.dll"
and
$path = (split-path $MyInvocation.MyCommand.Path)
$loggerPath = $path + "\Logger\release\Logger.ps1";
.$loggerPath;
$logger = Logger;
$logger.load($path + "\Logger\config\log4ps.xml","log.log");
and what is the best way to do it with regard to my problem?
How do I create a temp folder in windows temp folder?
Common Code In Powershell
You can just put the code you want to include in a different PS1 file, and then "dot source" that file to include it in the current scope:
. D:\script_common\MyCode.ps1
That's all there is to that.
Using a Module
You might consider using a module instead, which can be included using the Import-Module cmdlet. You might have used this to work with things like Active Directory, where you could do something like this:
Import-Module ActiveDirectory
In that case, you only need the name of the module because it's in a special directory.
To write your own modules in Powershell, you name the module with a .psm1 extension. Typically, you don't do free floating code in one of these; you write functions which are then available to the code which imports the module.
To import a script module from anywhere, use the full path:
Import-Module D:\script_common\MyModule.psm1
Module Paths
When you create your own modules, you can keep them any old place and then refer to them by their full path (as above). There are also several locations that Powershell looks for modules:
$PSHome\Modules (%Windir%\System32\WindowsPowerShell\v1.0\Modules) -- Reserved for modules that ship with Windows. Do not put things here.
$Home\Documents\WindowsPowerShell\Modules (%UserProfile%\Documents\WindowsPowerShell\Modules)
%ProgramFiles%\WindowsPowerShell\Modules -- this isn't mentioned in the link, and seems to be used more for Desired State Configuration modules (probably because it applies to the entire system).
These are defaults, but Powershell uses its own environment variable called PSModulePath to determine where to look, and much like PATH you can add your own folder(s) to that variable.
That lets you keep your modules in your own location. Do see the link for more info on how to structure your folders and how to do naming.
So as far as keeping your modules and "3rd party" modules in the same place, that depends on the 3rd party stuff. It may install its own modules in its own place and modify the path, or it may just let you put them wherever you want.
Creating a Temp Folder
You can use the TEMP or TMP environment variables to get the path of the temp folder. To retrieve them in Powershell, use $env:TEMP or $env:TMP.
You'll have to come up with a unique name of a folder to create in there. One way to do that might be to use a GUID:
$dirName = [System.Guid]::NewGuid().ToString()
New-Item -Path "$($env:TEMP)\$dirName"
You should be able to dot source the script like that:
. "C:\script_common\script.ps1"
after that you can use all the functions like they were in the script you are running.
But... the better way to do it would be to create a module with your common functions (How to here: Scripting Guy´s Blog. (TLDR Version: place functions into psm1 file, put into modulepath, import using Import-Module, profit)
For creating a folder:
New-Item C:\Temp\yourfolder -type directory
Here is my attempt to create a template system in powershell : https://github.com/kayasax/PowershellTemplate
It allows to reuse functions you save in the repository by using tags in the template
eg :
<include logging/log>
The content of the file log.ps1 found in the logging directory of the function repository will be inserted when tranforming template to script

How can I re-use/import script code in PowerShell scripts?

I have to create a PowerShell script which does exactly same thing as my previous script, but this time I have to read a CSV file instead of an XML file. My plan is to create a PowerShell script which has common functions required for both scripts and re-use this common script file in both main files.
Suppose I create 2 main files in 2 directories in C:\ drive and keep my common file and other 3rd party libraries in a folder of D:\ drive, e.g. C:\script_1_folder\Script1.ps1, C:\script_2_folder\Script2.ps1 and common file and 3rd party libraries will be in D:\script_common.
How do I call\re-use common file in my main files (how to get the path, do I have to create an instance of common file and how do I use it)
What is the difference between
$script_path = $myinvocation.invocationname;
$script_folder = split-path $script_path -parent;
write-host $script_folder
$script_name = split-path $script_path -leaf;
$current_folder = [system.io.directory]::getcurrentdirectory()
[system.io.directory]::setcurrentdirectory($script_folder)
Set-Location $script_folder
add-type -path ".\AlexFTPS-1.1.0\AlexPilotti.FTPS.Client.dll"
and
$path = (split-path $MyInvocation.MyCommand.Path)
$loggerPath = $path + "\Logger\release\Logger.ps1";
.$loggerPath;
$logger = Logger;
$logger.load($path + "\Logger\config\log4ps.xml","log.log");
and what is the best way to do it with regard to my problem?
How do I create a temp folder in windows temp folder?
Common Code In Powershell
You can just put the code you want to include in a different PS1 file, and then "dot source" that file to include it in the current scope:
. D:\script_common\MyCode.ps1
That's all there is to that.
Using a Module
You might consider using a module instead, which can be included using the Import-Module cmdlet. You might have used this to work with things like Active Directory, where you could do something like this:
Import-Module ActiveDirectory
In that case, you only need the name of the module because it's in a special directory.
To write your own modules in Powershell, you name the module with a .psm1 extension. Typically, you don't do free floating code in one of these; you write functions which are then available to the code which imports the module.
To import a script module from anywhere, use the full path:
Import-Module D:\script_common\MyModule.psm1
Module Paths
When you create your own modules, you can keep them any old place and then refer to them by their full path (as above). There are also several locations that Powershell looks for modules:
$PSHome\Modules (%Windir%\System32\WindowsPowerShell\v1.0\Modules) -- Reserved for modules that ship with Windows. Do not put things here.
$Home\Documents\WindowsPowerShell\Modules (%UserProfile%\Documents\WindowsPowerShell\Modules)
%ProgramFiles%\WindowsPowerShell\Modules -- this isn't mentioned in the link, and seems to be used more for Desired State Configuration modules (probably because it applies to the entire system).
These are defaults, but Powershell uses its own environment variable called PSModulePath to determine where to look, and much like PATH you can add your own folder(s) to that variable.
That lets you keep your modules in your own location. Do see the link for more info on how to structure your folders and how to do naming.
So as far as keeping your modules and "3rd party" modules in the same place, that depends on the 3rd party stuff. It may install its own modules in its own place and modify the path, or it may just let you put them wherever you want.
Creating a Temp Folder
You can use the TEMP or TMP environment variables to get the path of the temp folder. To retrieve them in Powershell, use $env:TEMP or $env:TMP.
You'll have to come up with a unique name of a folder to create in there. One way to do that might be to use a GUID:
$dirName = [System.Guid]::NewGuid().ToString()
New-Item -Path "$($env:TEMP)\$dirName"
You should be able to dot source the script like that:
. "C:\script_common\script.ps1"
after that you can use all the functions like they were in the script you are running.
But... the better way to do it would be to create a module with your common functions (How to here: Scripting Guy´s Blog. (TLDR Version: place functions into psm1 file, put into modulepath, import using Import-Module, profit)
For creating a folder:
New-Item C:\Temp\yourfolder -type directory
Here is my attempt to create a template system in powershell : https://github.com/kayasax/PowershellTemplate
It allows to reuse functions you save in the repository by using tags in the template
eg :
<include logging/log>
The content of the file log.ps1 found in the logging directory of the function repository will be inserted when tranforming template to script

Copy-Item cmdlet should only copy difference

Im writeing a backupscript useing powershell. I know that i could just use robocopy or rsync but i would like to do this in powershell. The problem i have has to do with the copy-item cmdlet. What my script does:
Read var's and fills them from a csv
Pings destination host
Checks if Outlook is open on source host and asks if it should close it
Then it should copy some folders onto the destination
My problem is that it always does a full copy of all files. I would like it to only copy the files that were changed or do not exist on the destination.
The second problem i have is that in Win7 there are hidden systemfolders in "Users/Documents" that link to "My Pictures" and "My Videos". I dont need to copy these but i didnt manage to exclude them useing the exclude agrument.
Just some quick and general suggestion...
I would like it to only copy the files that were changed
I would copy the files comparing the source and destination modified date
The second problem i have is that in Win7 there are hidden systemfolders in "Users/Documents" that link to "My Pictures" and "My Videos". I dont need to copy these but i didnt manage to exclude them useing the exclude agrument. :
Do not use copy-item directly, but use the output of get-childitem without force parameter. This will prevent to copy hidden or system files.