PowerShell स्क्रिप्ट सही फ़ाइलों को ज़िप नहीं कर रही है




scripting zip (2)

यदि आप (अस्थायी रूप से) |Out-Null अक्षम करते हैं, तो आप देखेंगे कि त्रुटि संदेश किसके साथ गुजरता है।
$ फाइलों में ऑब्जेक्ट्स होते हैं, न कि केवल फ़ाइल नामों की एक सरणी।

डिफ़ॉल्ट रूप से, यह Name गुण का उपयोग करके इसे कठोर बनाने की कोशिश करता है जिसमें पथ शामिल नहीं है - इसलिए 7zip फ़ाइलों को नहीं ढूंढ सकता है क्योंकि आप पथ को 7zip फ़ोल्डर में भी बदलते हैं (और-$ फ़ाइलें एकत्रित करना)

तो लाइन बदलो

$Files = Get-Childitem $TargetFolder -Recurse | Where {$_.LastWriteTime -le "$LastWrite"}

और append

| Select-Object -ExpandProperty FullName

थोडा सुधरा हुआ वर्सन स्रोत:

Function Zip{
    Param (
        [string]$zipFile,
        [string[]]$toBeZipped
    )
    & "C:\Program Files\7-Zip\7z.exe" A -tzip $zipFile $toBeZipped | Out-Null
}
$Days = "60"
$LastWrite = (Get-Date).Date.AddDays(-$Days)

$TargetFolder = "$($ENV:USERPROFILE)\Downloads\*"

$Files = Get-Childitem $TargetFolder -Recurse | 
   Where {$_.LastWriteTime -le $LastWrite} | 
     Select-Object -ExpandProperty FullName
$Files
Zip "$($ENV:USERPROFILE)\Desktop\TEST.zip" $Files
 Function Zip
{
    Param
    (
        [string]$zipFile
        ,
        [string[]]$toBeZipped
    )
    $CurDir = Get-Location
    Set-Location "C:\Program Files\7-Zip"
    .\7z.exe A -tzip $zipFile $toBeZipped | Out-Null
    Set-Location $CurDir
}
$Now = Get-Date
$Days = "60"
$TargetFolder = "C:\users\Admin\Downloads\*.*"
$LastWrite = $Now.AddDays(-$Days)
$Files = Get-Childitem $TargetFolder -Recurse | Where {$_.LastWriteTime -le "$LastWrite"}
$Files
Zip C:\Users\Admin\Desktop\TEST.zip $Files

मैं इस स्क्रिप्ट का परीक्षण कर रहा हूं जिसे मैंने ऑनलाइन पाया है। मेरी समस्या यह है कि लक्ष्य फ़ोल्डर में फ़ाइलों को ज़िप करने के बजाय, यह 7-ज़िप फ़ाइल फ़ाइल फ़ोल्डर की सामग्री को कॉपी और ज़िप कर रहा है। इसका क्या कारण हो सकता है? अग्रिम में धन्यवाद


Zip फ़ंक्शन के पूर्ण पथ के रूप में फ़ाइलें पास करें , उनकी .FullName संपत्ति (PSv3 + सिंटैक्स) का उपयोग करके:

Zip C:\Users\Admin\Desktop\TEST.zip $Files.FullName

समस्या यह है कि [System.IO.FileInfo] इंस्टेंसेस Get-ChildItem द्वारा लौटाए गए हैं Get-ChildItem [1] केवल उनकी फाइल के नाम की Get-ChildItem , जो कि आपके मामले में हुआ है, इसलिए आपके Zip फ़ंक्शन ने $toBeZipped मानों के सापेक्ष व्याख्या की $toBeZipped वर्तमान स्थान , जो उस बिंदु पर C:\Program Files\7-Zip

उस ने कहा, अपने फ़ंक्शन में Set-Location का पूरी तरह से उपयोग न करना बेहतर है , ताकि आप जिस घटना में वास्तविक रिश्तेदार पथ को पास करना चाहते हैं, उन्हें वर्तमान स्थान के सापेक्ष सही तरीके से व्याख्या किया जा सके:

Function Zip {
    Param
    (
        [Parameter(Mandatory)] # make sure a value is passed          
        [string]$zipFile
        ,
        [Parameter(Mandatory)] # make sure a value is passed
        [string[]]$toBeZipped
    )
    # Don't change the location, use & to invoke 7z by its full path.
    $null = & "C:\Program Files\7-Zip\7z.exe" A -tzip $zipFile $toBeZipped
    # You may want to add error handling here.
}

[१] जब Get-ChildItem आउटपुट केवल नाम दर्ज करने के लिए Get-ChildItem :

ध्यान दें:

इसलिए निम्न केवल Windows PowerShell में Get-ChildItem पर लागू होता है :

समस्या दुगनी है:

  • यहां तक ​​कि PowerShell के अंतर्निहित cmdlets फ़ाइल / निर्देशिका तर्क (पैरामीटर मान - पाइप लाइन के माध्यम से इनपुट के विपरीत) वस्तुओं के रूप में नहीं, बल्कि स्ट्रिंग (इस व्यवहार को इस GitHub मुद्दे में चर्चा की जा रही है) के रूप में बाँधते हैं।

  • इसलिए, मजबूत तर्क-पासिंग के लिए, आपको यह सुनिश्चित करने की आवश्यकता है कि आपका Get-ChildItem आउटपुट लगातार पूरे रास्तों को Get-ChildItem देता है, जो Get-ChildItem गारंटी नहीं देता है - और यह भूलना आसान है जब नाम-केवल स्ट्रिंग भी होता है तब भी आपको भुगतान करने की आवश्यकता होती है इस पर सभी का ध्यान है।

हमेशा .FullName प्रॉपर्टी वैल्यू को पास करना सबसे सरल वर्कअराउंड है , या किसी भी PowerShell प्रदाता के साथ विश्वसनीय संचालन के लिए, न कि केवल फाइलसिस्टम .PSPath

[System.IO.FileInfo] और [System.IO.DirectoryInfo] एक Get-ChildItem कमांड द्वारा आउटपुट का उदाहरण उनकी फ़ाइल के नाम , यदि और केवल तभी :

  • यदि एक या अधिक शाब्दिक निर्देशिका पथ को -LiteralPath या -LiteralPath (संभवतः 1 स्थितीय तर्क के रूप में) पास किया जाता है या कोई भी पथ पारित नहीं किया जाता है (वर्तमान स्थान को लक्षित करें); यह है, अगर निर्देशिका की सामग्री enumerated हैं।

  • और भी -Include / -Exclude मापदंडों का उपयोग नहीं करता है (चाहे -Filter का उपयोग किया जाता है कोई फर्क नहीं पड़ता)।

  • इसके विपरीत, चाहे या नहीं निम्नलिखित भी मौजूद हैं कोई फर्क नहीं पड़ता:

    • -Filter (वैकल्पिक रूप से द्वितीय स्थितीय तर्क के रूप में, लेकिन ध्यान दें कि एक वाइल्डकार्ड अभिव्यक्ति जैसे कि *.txt 1 (और संभवतः केवल) स्थितीय तर्क के रूप में निर्दिष्ट करता है -Path पैरामीटर को बांधता है)
    • -Recurse ( अपने आप से , लेकिन ध्यान दें कि इसे अक्सर -Include / -Exclude के साथ जोड़ा जाता है)

उदाहरण के आदेश:

# NAME-ONLY stringification:

Get-ChildItem | % ToString # no target path

Get-ChildItem . | % ToString # path is literal dir.

Get-ChildItem . *.txt | % ToString  # path is literal dir., combined with -Filter

# FULL PATH stringification:

Get-ChildItem foo* | % ToString # non-literal path (wildcard)

Get-ChildItem -Recurse -Include *.txt | % ToString # use of -Include

Get-ChildItem file.txt | % ToString # *file* path




7zip