পাওয়ারশেল জিপ ফাইল সিঙ্ক্রোনসিভভাবে


10

পাওয়ারশেল স্ক্রিপ্টে, আমি ফোল্ডারটি মোছার আগে একটি ফোল্ডার জিপ করতে চাই। আমি নিম্নলিখিতগুলি চালাচ্ছি (আমি স্নিপেটটি কোথায় পেয়েছি তা মনে নেই):

function Compress-ToZip
{
    param([string]$zipfilename)

    if(-not (test-path($zipfilename)))
    {
        set-content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
        (Get-ChildItem $zipfilename).IsReadOnly = $false   
    }

    $shellApplication = new-object -com shell.application
    $zipPackage = $shellApplication.NameSpace($zipfilename)

    foreach($file in $input)
    {
         $zipPackage.CopyHere($file.FullName)

    }
}

এই স্নিপেটটি প্রকৃতপক্ষে ফোল্ডারটি সংকুচিত করে, তবে একটি অ্যাসিনক্রোনাস উপায়ে। প্রকৃতপক্ষে, শেল.অ্যাপ্লিকেশন অবজেক্টগুলির কপিহির পদ্ধতিটি সংক্ষেপণ শুরু করে এবং এর সমাপ্তির জন্য অপেক্ষা করে না। আমার স্ক্রিপ্টগুলির পরবর্তী বিবৃতিগুলি তখন জগাখিচু হয়ে যায় (জিপ ফাইল প্রক্রিয়াটি সম্পন্ন না হওয়ায়)।

কোন পরামর্শ? সম্ভব হলে আমি কোনও এক্সিকিউটেবল ফাইল যুক্ত করা এবং খাঁটি উইন্ডোজ বৈশিষ্ট্যগুলিতে থাকা এড়াতে চাই।

আমার PS1 ফাইলের সম্পূর্ণ বিষয়বস্তু ডিবিটির আসল নাম বিয়োগের সম্পাদনা করুন edit স্ক্রিপ্টের লক্ষ্য হ'ল এসকিউএল ডিবি-র একটি সেট ব্যাকআপ করা, তারপরে বর্তমান তারিখের সাথে নামযুক্ত ফোল্ডারে একক প্যাকেজে ব্যাকআপগুলি জিপ করুন:

$VerbosePreferenceBak = $VerbosePreference
$VerbosePreference = "Continue"

add-PSSnapin SqlServerCmdletSnapin100

function BackupDB([string] $dbName, [string] $outDir)
{
    Write-Host "Backup de la base :  $dbName"
    $script = "BACKUP DATABASE $dbName TO DISK = '$outDir\$dbName.bak' WITH FORMAT, COPY_ONLY;"

    Invoke-Sqlcmd -Query "$script" -ServerInstance "." -QueryTimeOut 600
    Write-Host "Ok !"
}

function Compress-ToZip
{
    param([string]$zipfilename)

Write-Host "Compression du dossier"

    if(-not (test-path($zipfilename)))
    {
        set-content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
        (Get-ChildItem $zipfilename).IsReadOnly = $false   
    }

    $shellApplication = new-object -com shell.application
    $zipPackage = $shellApplication.NameSpace($zipfilename)

    foreach($file in $input)
    {
         $zipPackage.CopyHere($file.FullName)       
    }
Write-Host "Press any key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

}


$targetDir = "E:\Backup SQL"
$date = Get-Date -format "yyyy-MM-dd"
$newDir = New-Item -ItemType Directory "$targetDir\$date\sql" -Force

BackupDB  "database 1" "$newDir"
BackupDB  "database 2" "$newDir"
BackupDB  "database 3" "$newDir"

Get-Item $newDir | Compress-ToZip "$targetDir\$date\sql_$date.zip"


Write-Host "."
remove-item $newDir -Force -Confirm:$false -Recurse

$VerbosePreference = $VerbosePreferenceBak

এটি সিঙ্ক্রোনাস হলে এটি কাজ করে কিনা তা দেখার জন্য: আপনি যদি পূর্বসূচির পরে নিম্নলিখিত কোড যুক্ত করেন তবে এটি কী প্রত্যাশার সাথে কাজ করে? Write-Host "Press any key to continue ..." লাইন 1: লাইন 2:$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
কেরি

এবং পরীক্ষার সময় আমি স্পষ্টতই ধরে নিচ্ছি যে আপনি জিপ প্রক্রিয়াটি সম্পন্ন হয়েছে তা ম্যানুয়ালি নিশ্চিত না করা পর্যন্ত আপনি "চালিয়ে যাওয়ার জন্য কোনও কী চাপবেন না"।
কেরি

@ কেরি: আমি যখন আপনার ম্যানুয়াল পরীক্ষাটি যুক্ত করি তখন এটি বাস্তবে প্রত্যাশার সাথে কাজ করে
স্টিভ বি

উত্তর:


5

অবশেষে আমি একটি পরিষ্কার উপায় খুঁজে পেয়েছি, কম বস্তুর বৈশিষ্ট্য নিয়ে খেলছি। বিশেষত, নিম্নলিখিত স্নিপেটটি ফাইলটি জিপ ফাইলে উপস্থিত থাকলে তা পরীক্ষা করতে পারে:

foreach($file in $input)
{
    $zipPackage.CopyHere($file.FullName)    
    $size = $zipPackage.Items().Item($file.Name).Size
    while($zipPackage.Items().Item($file.Name) -Eq $null)
    {
        start-sleep -seconds 1
        write-host "." -nonewline
    }
}

সম্পূর্ণ স্ক্রিপ্টটি নিম্নলিখিত:

$VerbosePreferenceBak = $VerbosePreference
$VerbosePreference = "Continue"

add-PSSnapin SqlServerCmdletSnapin100

function BackupDB([string] $dbName, [string] $outDir) {
    Write-Host "Backup de la base :  $dbName"
    $script = "BACKUP DATABASE $dbName TO DISK = '$outDir\$dbName.bak' WITH FORMAT, COPY_ONLY;"

    Invoke-Sqlcmd -Query "$script" -ServerInstance "." -QueryTimeOut 600
    Write-Host "Ok !"
}

function Compress-ToZip {
    param([string]$zipfilename)

    Write-Host "Compression du dossier"

    if(-not (test-path($zipfilename)))  {
        set-content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
        (Get-ChildItem $zipfilename).IsReadOnly = $false   
    }

    $shellApplication = new-object -com shell.application
    $zipPackage = $shellApplication.NameSpace($zipfilename)

    foreach($file in $input) {
        $zipPackage.CopyHere($file.FullName)    
        $size = $zipPackage.Items().Item($file.Name).Size
        while($zipPackage.Items().Item($file.Name) -Eq $null)
        {
            start-sleep -seconds 1
            write-host "." -nonewline
        }
        write-host "."
    }      
}


$targetDir = "E:\Backup SQL"
$date = Get-Date -format "yyyy-MM-dd"
$newDir = New-Item -ItemType Directory "$targetDir\$date\sql" -Force

BackupDB  "DB1" "$newDir"
BackupDB  "DB2" "$newDir"
BackupDB  "DB3" "$newDir"
BackupDB  "DB4" "$newDir"

Get-ChildItem "$newDir" | Compress-ToZip "$targetDir\$date\sql_$date.zip"

remove-item $newDir -Force -Confirm:$false -Recurse

$VerbosePreference = $VerbosePreferenceBak

আপনি কীভাবে এটি ভিবিতে ব্যবহার করতে পারেন?
ম্যাকগাইভার 21

@ ল্যান্ড্রো: আপনার মানে ভিবি স্ক্রিপ্ট? যেহেতু পাওয়ারশেল এবং ভিবিএস স্ক্রিপ্ট উভয়ই স্ক্রিপ্টিং ভাষা, COM অবজেক্টের সাথে কাজ করতে সক্ষম, আপনি এখানে অনেক অসুবিধা ছাড়াই আচরণটির প্রতিলিপি করতে সক্ষম হবেন
স্টিভ বি

1

কারণ আপনি ম্যানুয়ালি এটিকে থামিয়ে দেওয়ার সময় এটি দুর্দান্ত কাজ করেছে, এখানে একটি অস্থায়ী হ্যাক যা "ডান" সমাধানটি না পাওয়া পর্যন্ত আপনি ব্যবহার করতে সক্ষম হতে পারেন। সাধারণত "বিলম্ব" এবং "টাইমার" ব্যবহার করা মিশনের সমালোচনামূলক বিষয়গুলির জন্য আপনি যা করেন তা নয়। এটি বলেছে, আরও ভাল উত্তর না পাওয়া পর্যন্ত আপনি এটি করতে পারেন এবং এটি কার্যকর হয় কিনা তা দেখতে পারেন:

  • প্রক্রিয়াটি কয়েক বার নিজেই করুন এবং TIME সেকেন্ডে সাধারণত জিপ প্রক্রিয়াটি শেষ হতে কত সময় লাগে। যদি ডাটাবেসের আকার প্রতিদিন প্রতিদিন একই হয় তবে এটি শেষ হতে সময়টি সম্ভবত একই সময়ে প্রায় গড় হয়।

  • ধরা যাক আপনি আপনার ম্যানুয়াল পরীক্ষায় গড়ে 60 সেকেন্ড পান। রক্ষণশীল হন এবং এটি 4 বা তত বেশি করে গুণান কারণ এটি সম্ভবত "স্বাভাবিক" দিনে স্বাভাবিকের চেয়ে 4 গুণ বেশি সময় নেয় না। সুতরাং এখন আপনার 240 সেকেন্ড (60 সেকেন্ড গড় গড় 4)।

  • সুতরাং আপাতত, "কোডটি চালিয়ে যাওয়ার জন্য কোনও কী চাপুন" পরিবর্তে, কোডটি একটি ডিলে দিয়ে প্রতিস্থাপন করুন যাতে স্ক্রিপ্টটি কিছুক্ষণ জিপ শেষ হওয়ার জন্য অপেক্ষা করতে থাকে to এটির জন্য কিছু টুইট এবং সময় অনুমান করা দরকার এবং এটি একটি ভাল পদ্ধতির নয়। তবে এক চিমটি ...

  • যাইহোক, আপনি যদি এটি চেষ্টা করতে চান তবে কোডটি এতে পরিবর্তন করুন:

পাওয়ারশেল ভি 1 ব্যবহার করা হলে:

foreach($file in $input)
{
  $zipPackage.CopyHere($file.FullName)       
}

[System.Threading.Thread]::Sleep(240000)

পাওয়ারশেল ভি 2 ব্যবহার করে, তার পরিবর্তে স্লিপ সেমিডলেট ব্যবহার করুন:

foreach($file in $input)
{
   $zipPackage.CopyHere($file.FullName)       
}

Start-Sleep -Second 240

ভি 1 এ বারের সাথে ঝামেলা করতে এটি মিলিসেকেন্ড ব্যবহার করে। (সুতরাং 10 সেকেন্ড = 10000)

ভি 2 এর সাথে ঝামেলা করতে এটি সেকেন্ড ব্যবহার করে। (240 = 240 সেকেন্ড)

আমি এটি কখনই উত্পাদনে ব্যবহার করতে পারি না তবে যদি এটি কোনও চুক্তির মধ্যে এত বড় না হয় এবং এটি সময়ের 99% জরিমানা কাজ করে প্রমাণিত হয় তবে এটি যথেষ্ট ভাল হতে পারে।


অবশেষে আমি সমাধানটি খুঁজে পেলাম। আমি যাইহোক আপনার সাহায্যের প্রশংসা করি। থেক্স
স্টিভ বি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.