{"id":8908,"date":"2022-02-22T14:38:29","date_gmt":"2022-02-22T19:38:29","guid":{"rendered":"https:\/\/jdhitsolutions.com\/blog\/?p=8908"},"modified":"2022-02-22T14:38:31","modified_gmt":"2022-02-22T19:38:31","slug":"copy-to-multiple-destinations-with-powershell","status":"publish","type":"post","link":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8908\/copy-to-multiple-destinations-with-powershell\/","title":{"rendered":"Copy to Multiple Destinations with PowerShell"},"content":{"rendered":"\n<p>In honor of today, 2\/22\/2022, I thought I'd share a PowerShell function that allows you to copy files to multiple destinations. If you look at help for Copy-Item, which you should, you'll see that the Destination parameter does not take an array. That's ok. I can fix that. However, I have a disclaimer that you should consider this a proof-of-concept and not production-ready code.<\/p>\n\n\n\n<p>The first step was to create a copy of the Copy-Item cmdlet. I used the <a href=\"https:\/\/github.com\/jdhitsolutions\/PSScriptTools\/blob\/master\/docs\/Copy-Command.md\" target=\"_blank\" rel=\"noreferrer noopener\">Copy-Command <\/a>function from the <a href=\"https:\/\/github.com\/jdhitsolutions\/PSScriptTools\" target=\"_blank\" rel=\"noreferrer noopener\">PSScriptTools <\/a>module, which you can install from the PowerShell Gallery. I used the function to create a \"wrapper\" function based on Copy-Item. Copy-Command copies the original parameters. I edited the Destination parameter to accept an array of locations.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">[Parameter(\n    Mandatory,\n    Position = 1,\n    ValueFromPipelineByPropertyName,\n    HelpMessage = \"Specify a file system destination.\"\n)]\n[ValidateScript({Test-Path $_})]\n[string[]]$Destination,<\/code><\/pre>\n\n\n\n<p>Because the parameters of my new function are identical to Copy-Item, I can use PSBoundParameters to build a Copy-Item command. However, I need to remove the Destination parameter since Copy-Item isn't written to support an array.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">  [void]($PSBoundParameters.Remove(\"Destination\"))<\/code><\/pre>\n\n\n\n<p>This line goes in the Process scriptblock because I defined Destination to take pipeline input by value.<\/p>\n\n\n\n<p>The concept behind my new function is quite simple. Run a Copy-Item command foreach destination. But, if I'm copying many files, I want this to run quickly and more or less in parallel. That's when I realized I could use Start-ThreadJob. If you don't have the ThreadJob module installed, you can get it from the PowerShell Gallery. Unlike Start-Job, which spins up a new runspace, Start-Threadjob creates a job in a separate thread within the local process. This tends to be faster. <\/p>\n\n\n\n<p>The tricky part was figuring out how to pass parameters. I could have splatted parameter values.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">start-threadjob {param($splat,$location) Copy-item @splat -destination $location} -arguments @($psboundparameters,$location)<\/code><\/pre>\n\n\n\n<p>And I will keep this concept in mind for future projects. Instead, I decided to recreate the parameters from PSBoundParameters.  If I can create a command string, I can turn that into a scriptblock, which I can then pass to Start-ThreadJob.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">$PSBoundParameters.GetEnumerator() | ForEach-Object -Begin { $p = \"Copy-Item\" } -Process {\n    if ($_.value -eq $True) {\n        $p += \" -$($_.key)\"\n    }\n    else {\n        $p += \" -$($_.key) $($_.value)\"\n    }\n} -End {\n    $p += \" -destination $location\"\n}<\/code><\/pre>\n\n\n\n<p>In the ForEach-Object Begin parameter, I'm initializing a string with the Copy-Item command. Then for each enumerated PSBoundParameter, I reconstruct the parameter name and value. The \"gotcha\" is handling switches like -Recurse or -WhatIf. So if the value is equal to True, I'll assume the key is a switch parameter. Usually, I abstain from explicit boolean comparisons in an If statement, but in this case, I am checking the value of $_.value and not merely if it exists. When I'm finished, $p will look like \"Copy-Item -Verbose -WhatIf -Path C:\\Scripts\\WMIDiag.exe -destination d:\\temp\". I can turn that into a scriptblock and run it as a ThreadJob.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">$sb = [scriptblock]::Create($p)\n#WhatIf code ommitted here\n$j = Start-ThreadJob $sb<\/code><\/pre>\n\n\n\n<p>The approach I am taking, depending on how you are running the copy command, could create a thread job for every file to be copied. There is a bit of overhead, so this may not perform well for many small files, but I'd take it when copying large files.<\/p>\n\n\n\n<p>If I trust that I'll never make a mistake, I could stop. But, I might want to use -Passthru from Copy-Item. Or need to see if there are any errors. This means I will have to get the job results. In my functions' Begin block, I'll initialize a generic list.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">$jobs = [System.Collections.Generic.List[object]]::new()<\/code><\/pre>\n\n\n\n<p>I'll add each job to the list created in the Process script block.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\"> $jobs.add($j)<\/code><\/pre>\n\n\n\n<p>In the End scriptblock, assuming there are jobs, I'll wait for the last of them to complete, get the results, and remove the job.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">If ($jobs) {\n    Write-Verbose \"$((Get-Date).TimeOfDay) [END    ] Processing $($jobs.count) thread jobs\"\n    $jobs | Wait-Job | Receive-Job\n    $jobs | Remove-Job\n}<\/code><\/pre>\n\n\n\n<p>Now, I can copy files to 2 (or more) directories with one command!<\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-style-default\"><a href=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/02\/cp2.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"144\" src=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/02\/cp2-1024x144.png\" alt=\"copy files to multiple locations.\" class=\"wp-image-8910\" srcset=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/02\/cp2-1024x144.png 1024w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/02\/cp2-300x42.png 300w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/02\/cp2-768x108.png 768w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/02\/cp2-850x120.png 850w, https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/02\/cp2.png 1074w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<p>Want to try?<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"powershell\" class=\"language-powershell\">#requires -version 5.1\n#requires -module ThreadJob\n\nFunction Copy-ItemToMultiDestination {\n    [CmdletBinding(\n        SupportsShouldProcess,\n        ConfirmImpact = 'Medium'\n    )]\n    [alias(\"cp2\")]\n    Param(\n        [Parameter(\n            Mandatory,\n            Position = 0,\n            ValueFromPipeline,\n            ValueFromPipelineByPropertyName,\n            HelpMessage = \"Specify a file system source path.\"\n        )]\n        [ValidateScript({ Test-Path $_ })]\n        [string[]]$Path,\n        [Parameter(\n            Mandatory,\n            Position = 1,\n            ValueFromPipelineByPropertyName,\n            HelpMessage = \"Specify a file system destination.\"\n        )]\n        [ValidateScript({ Test-Path $_ })]\n        [string[]]$Destination,\n        [switch]$Container,\n        [switch]$Force,\n        [string]$Filter,\n        [string[]]$Include,\n        [string[]]$Exclude,\n        [switch]$Recurse,\n        [switch]$PassThru,\n        [Parameter(ValueFromPipelineByPropertyName)]\n        [pscredential]\n        [System.Management.Automation.CredentialAttribute()]$Credential\n    )\n\n    Begin {\n\n        Write-Verbose \"$((Get-Date).TimeOfDay) [BEGIN  ] Starting $($MyInvocation.Mycommand)\"\n        #initialize a list for thread jobs\n        $jobs = [System.Collections.Generic.List[object]]::new()\n\n    } #begin\n\n    Process {\n        [void]($PSBoundParameters.Remove(\"Destination\"))\n\n        foreach ($location in $Destination) {\n            Write-Verbose \"$((Get-Date).TimeOfDay) [PROCESS] Creating copy job\"\n            $PSBoundParameters.GetEnumerator() | ForEach-Object -Begin { $p = \"Copy-Item\" } -Process {\n                if ($_.value -eq $True) {\n                    $p += \" -$($_.key)\"\n                }\n                else {\n                    $p += \" -$($_.key) $($_.value)\"\n                }\n            } -End {\n                $p += \" -destination $location\"\n            }\n\n            Write-Verbose \"$((Get-Date).TimeOfDay) [PROCESS] $p\"\n            $sb = [scriptblock]::Create($p)\n\n            #Start-ThreadJob doesn't support -whatif\n            if ($PSCmdlet.ShouldProcess($p)) {\n                $j = Start-ThreadJob $sb\n                #add each job to the list\n                $jobs.add($j)\n            }\n        } #foreach location\n\n    } #process\n\n    End {\n        If ($jobs) {\n            Write-Verbose \"$((Get-Date).TimeOfDay) [END    ] Processing $($jobs.count) thread jobs\"\n            $jobs | Wait-Job | Receive-Job\n            $jobs | Remove-Job\n        }\n\n        Write-Verbose \"$((Get-Date).TimeOfDay) [END    ] Ending $($MyInvocation.Mycommand)\"\n\n    } #end\n\n} #end function Copy-ItemToMultiDestination<\/code><\/pre>\n\n\n\n<p>Remember, this is a proof of concept. Although my mind is already whirling on other commands I could \"update\" using some of these techniques. Have fun.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In honor of today, 2\/22\/2022, I thought I&#8217;d share a PowerShell function that allows you to copy files to multiple destinations. If you look at help for Copy-Item, which you should, you&#8217;ll see that the Destination parameter does not take an array. That&#8217;s ok. I can fix that. However, I have a disclaimer that you&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"New on the blog: Copying Files to Multiple Destinations with #PowerShell","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[4,8],"tags":[666,224,534,540,631],"class_list":["post-8908","post","type-post","status-publish","format-standard","hentry","category-powershell","category-scripting","tag-copy-item","tag-function","tag-powershell","tag-scripting","tag-threadjob"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Copy to Multiple Destinations with PowerShell &#8226; The Lonely Administrator<\/title>\n<meta name=\"description\" content=\"See how I create a new version of Copy-Item to copy files to multiple destinations in PowerShell. You might use these techniques in your work.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/jdhitsolutions.com\/blog\/powershell\/8908\/copy-to-multiple-destinations-with-powershell\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Copy to Multiple Destinations with PowerShell &#8226; The Lonely Administrator\" \/>\n<meta property=\"og:description\" content=\"See how I create a new version of Copy-Item to copy files to multiple destinations in PowerShell. You might use these techniques in your work.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/jdhitsolutions.com\/blog\/powershell\/8908\/copy-to-multiple-destinations-with-powershell\/\" \/>\n<meta property=\"og:site_name\" content=\"The Lonely Administrator\" \/>\n<meta property=\"article:published_time\" content=\"2022-02-22T19:38:29+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-02-22T19:38:31+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/02\/cp2-1024x144.png\" \/>\n<meta name=\"author\" content=\"Jeffery Hicks\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@JeffHicks\" \/>\n<meta name=\"twitter:site\" content=\"@JeffHicks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jeffery Hicks\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8908\\\/copy-to-multiple-destinations-with-powershell\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8908\\\/copy-to-multiple-destinations-with-powershell\\\/\"},\"author\":{\"name\":\"Jeffery Hicks\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"headline\":\"Copy to Multiple Destinations with PowerShell\",\"datePublished\":\"2022-02-22T19:38:29+00:00\",\"dateModified\":\"2022-02-22T19:38:31+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8908\\\/copy-to-multiple-destinations-with-powershell\\\/\"},\"wordCount\":619,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"image\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8908\\\/copy-to-multiple-destinations-with-powershell\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/02\\\/cp2-1024x144.png\",\"keywords\":[\"Copy-Item\",\"Function\",\"PowerShell\",\"Scripting\",\"ThreadJob\"],\"articleSection\":[\"PowerShell\",\"Scripting\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8908\\\/copy-to-multiple-destinations-with-powershell\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8908\\\/copy-to-multiple-destinations-with-powershell\\\/\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8908\\\/copy-to-multiple-destinations-with-powershell\\\/\",\"name\":\"Copy to Multiple Destinations with PowerShell &#8226; The Lonely Administrator\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8908\\\/copy-to-multiple-destinations-with-powershell\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8908\\\/copy-to-multiple-destinations-with-powershell\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/02\\\/cp2-1024x144.png\",\"datePublished\":\"2022-02-22T19:38:29+00:00\",\"dateModified\":\"2022-02-22T19:38:31+00:00\",\"description\":\"See how I create a new version of Copy-Item to copy files to multiple destinations in PowerShell. You might use these techniques in your work.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8908\\\/copy-to-multiple-destinations-with-powershell\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8908\\\/copy-to-multiple-destinations-with-powershell\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8908\\\/copy-to-multiple-destinations-with-powershell\\\/#primaryimage\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/02\\\/cp2.png\",\"contentUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2022\\\/02\\\/cp2.png\",\"width\":1074,\"height\":151},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/8908\\\/copy-to-multiple-destinations-with-powershell\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"PowerShell\",\"item\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/category\\\/powershell\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Copy to Multiple Destinations with PowerShell\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/\",\"name\":\"The Lonely Administrator\",\"description\":\"Practical Advice for the Automating IT Pro\",\"publisher\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\",\"name\":\"Jeffery Hicks\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"caption\":\"Jeffery Hicks\"},\"logo\":{\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Copy to Multiple Destinations with PowerShell &#8226; The Lonely Administrator","description":"See how I create a new version of Copy-Item to copy files to multiple destinations in PowerShell. You might use these techniques in your work.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8908\/copy-to-multiple-destinations-with-powershell\/","og_locale":"en_US","og_type":"article","og_title":"Copy to Multiple Destinations with PowerShell &#8226; The Lonely Administrator","og_description":"See how I create a new version of Copy-Item to copy files to multiple destinations in PowerShell. You might use these techniques in your work.","og_url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8908\/copy-to-multiple-destinations-with-powershell\/","og_site_name":"The Lonely Administrator","article_published_time":"2022-02-22T19:38:29+00:00","article_modified_time":"2022-02-22T19:38:31+00:00","og_image":[{"url":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/02\/cp2-1024x144.png","type":"","width":"","height":""}],"author":"Jeffery Hicks","twitter_card":"summary_large_image","twitter_creator":"@JeffHicks","twitter_site":"@JeffHicks","twitter_misc":{"Written by":"Jeffery Hicks","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8908\/copy-to-multiple-destinations-with-powershell\/#article","isPartOf":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8908\/copy-to-multiple-destinations-with-powershell\/"},"author":{"name":"Jeffery Hicks","@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"headline":"Copy to Multiple Destinations with PowerShell","datePublished":"2022-02-22T19:38:29+00:00","dateModified":"2022-02-22T19:38:31+00:00","mainEntityOfPage":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8908\/copy-to-multiple-destinations-with-powershell\/"},"wordCount":619,"commentCount":2,"publisher":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"image":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8908\/copy-to-multiple-destinations-with-powershell\/#primaryimage"},"thumbnailUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/02\/cp2-1024x144.png","keywords":["Copy-Item","Function","PowerShell","Scripting","ThreadJob"],"articleSection":["PowerShell","Scripting"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/jdhitsolutions.com\/blog\/powershell\/8908\/copy-to-multiple-destinations-with-powershell\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8908\/copy-to-multiple-destinations-with-powershell\/","url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8908\/copy-to-multiple-destinations-with-powershell\/","name":"Copy to Multiple Destinations with PowerShell &#8226; The Lonely Administrator","isPartOf":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8908\/copy-to-multiple-destinations-with-powershell\/#primaryimage"},"image":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8908\/copy-to-multiple-destinations-with-powershell\/#primaryimage"},"thumbnailUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/02\/cp2-1024x144.png","datePublished":"2022-02-22T19:38:29+00:00","dateModified":"2022-02-22T19:38:31+00:00","description":"See how I create a new version of Copy-Item to copy files to multiple destinations in PowerShell. You might use these techniques in your work.","breadcrumb":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8908\/copy-to-multiple-destinations-with-powershell\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/jdhitsolutions.com\/blog\/powershell\/8908\/copy-to-multiple-destinations-with-powershell\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8908\/copy-to-multiple-destinations-with-powershell\/#primaryimage","url":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/02\/cp2.png","contentUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/02\/cp2.png","width":1074,"height":151},{"@type":"BreadcrumbList","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8908\/copy-to-multiple-destinations-with-powershell\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"PowerShell","item":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},{"@type":"ListItem","position":2,"name":"Copy to Multiple Destinations with PowerShell"}]},{"@type":"WebSite","@id":"https:\/\/jdhitsolutions.com\/blog\/#website","url":"https:\/\/jdhitsolutions.com\/blog\/","name":"The Lonely Administrator","description":"Practical Advice for the Automating IT Pro","publisher":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/jdhitsolutions.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9","name":"Jeffery Hicks","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","url":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","caption":"Jeffery Hicks"},"logo":{"@id":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg"}}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":8777,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8777\/copy-powershell-history-command\/","url_meta":{"origin":8908,"position":0},"title":"Copy PowerShell History Command","author":"Jeffery Hicks","date":"January 11, 2022","format":false,"excerpt":"I thought I'd share a short but useful PowerShell utility. This is something that is very handy when I am writing. As you know, PowerShell maintains a command history in your PowerShell session. You can view history with the Get-History cmdlet or its alias h. To re-rerun a command use\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/ch.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/ch.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/ch.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/ch.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/ch.png?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2022\/01\/ch.png?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":8409,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/8409\/custom-csv-import-with-powershell\/","url_meta":{"origin":8908,"position":1},"title":"Custom CSV Import with PowerShell","author":"Jeffery Hicks","date":"May 18, 2021","format":false,"excerpt":"I am always looking for opportunities to use PowerShell in a way that adds value to my work. And hopefully yours. This is one of the reasons it is worth the time and effort to learn PowerShell. It can be used in so many ways beyond the out-of-the-box commands. Once\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/05\/importcsv-customtype.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/05\/importcsv-customtype.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/05\/importcsv-customtype.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2021\/05\/importcsv-customtype.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":4581,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/4581\/powershell-friday-fun-capture-the-command\/","url_meta":{"origin":8908,"position":2},"title":"PowerShell Friday Fun: Capture the Command","author":"Jeffery Hicks","date":"October 30, 2015","format":false,"excerpt":"This week's Friday Fun actually has a purpose, at least for me. But I always hope you'll pick up a tip or two that you can use in your own PowerShell work. Because I write a lot about PowerShell, I am constantly copying pasting between my PowerShell session and usually\u2026","rel":"","context":"In &quot;Friday Fun&quot;","block_context":{"text":"Friday Fun","link":"https:\/\/jdhitsolutions.com\/blog\/category\/friday-fun\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":933,"url":"https:\/\/jdhitsolutions.com\/blog\/scripting\/933\/powershell-ise-new-function\/","url_meta":{"origin":8908,"position":3},"title":"PowerShell ISE New Function","author":"Jeffery Hicks","date":"September 16, 2010","format":false,"excerpt":"Yesterday I showed how to add a menu choice to the PowerShell ISE to insert the current date and time. Today I have something even better. At least it's something I've needed for awhile. I write a lot of advanced functions in PowerShell. I'm often cutting and pasting from previous\u2026","rel":"","context":"In &quot;PowerShell ISE&quot;","block_context":{"text":"PowerShell ISE","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell-ise\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2010\/09\/ise-addons.png?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":4895,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/4895\/friday-fun-a-sysinternals-powershell-workflow\/","url_meta":{"origin":8908,"position":4},"title":"Friday Fun: A SysInternals PowerShell Workflow","author":"Jeffery Hicks","date":"February 12, 2016","format":false,"excerpt":"Over the years I've come up with a number of PowerShell tools to download the SysInternals tools to my desktop. And yes, I know that with PowerShell 5 and PowerShellGet I could download and install a SysInternals package. But that assumes the package is current.\u00a0 But that's not really the\u2026","rel":"","context":"In &quot;Friday Fun&quot;","block_context":{"text":"Friday Fun","link":"https:\/\/jdhitsolutions.com\/blog\/category\/friday-fun\/"},"img":{"alt_text":"image","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2016\/02\/image_thumb-5.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2016\/02\/image_thumb-5.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2016\/02\/image_thumb-5.png?resize=525%2C300 1.5x"},"classes":[]},{"id":2605,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2605\/copy-and-mount-a-cd-with-powercli\/","url_meta":{"origin":8908,"position":5},"title":"Copy and Mount a CD with PowerCLI","author":"Jeffery Hicks","date":"November 30, 2012","format":false,"excerpt":"The other day I realized I needed to rebuild my SQL Server 2012 installation which I'm running on a virtual machine running on an ESX box. Given that I have PowerCLI and I like to do things from the command prompt when I can, I decided to mount the SQL\u2026","rel":"","context":"In &quot;PowerCLI&quot;","block_context":{"text":"PowerCLI","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powercli\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/11\/PowerCLI-150x150.png?resize=350%2C200","width":350,"height":200},"classes":[]}],"_links":{"self":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/8908","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/comments?post=8908"}],"version-history":[{"count":0,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/8908\/revisions"}],"wp:attachment":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/media?parent=8908"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/categories?post=8908"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/tags?post=8908"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}