iT邦幫忙

0

關於「代碼該如何優化」的問題

  • 分享至 

  • xImage

工具:PowerShell ISE

小弟最近再寫一支簡易的Script,該Script主要目的不是這次發問的討論重點,目前該Script可用性已滿足需求了,但是看到If底下那麼多重複的Code,整個看了就很「阿雜」

一直Google也沒找到什麼眉角,甚至連關鍵字都相當不確定,因此秉持著學習的精神,上來和大家請益,『我該如何把If...elseIf重複的Code變成一個Function來使用呢?』

廢話不再多說,直接上Code

for ($i= 0; $i -le 1; $i++){
$SIDNu = (import-Csv "D:\Script test\SID.csv").SID[$i]
$NameNu = (import-Csv "D:\Script test\SID.csv").Name[$i]
Mount-DiskImage -ImagePath "D:\Script test\Disk\UVHD-$SIDNu.vhdx"
$DiskNu = (Get-WmiObject -Class Win32_LogicalDisk -Filter "VolumeName='User Disk'" | Select-Object DeviceID).DeviceID

    if ( $NameNu[-1] -eq "0" -or $NameNu[-1] -eq "1" )
    {
        New-Item "D:\Script test\PC1\$NameNu.bk\" -ItemType "directory"
        $Source = "$DiskNu\Downloads"
        $Destn = "D:\Script test\PC1\$NameNu.bk\Downloads"
        robocopy "$Source" "$Destn" /e /dcopy:t /xo /xj /MT:100

        $Source = "$DiskNu\Favorites"
        $Destn = "D:\Script test\PC1\$NameNu.bk\Favorites"
        robocopy "$Source" "$Destn" /e /dcopy:t /xo /xj /MT:100

        $Source = "$DiskNu\Desktop"
        $Destn = "D:\Script test\PC1\$NameNu.bk\Desktop"
        robocopy "$Source" "$Destn" /e /dcopy:t /xo /xj /MT:100
    }
    elseif( $NameNu[-1] -eq "2" -or $NameNu[-1] -eq "3") 
    {
        $Source = "$DiskNu\Downloads"
        $Destn = "D:\Script test\PC2\$NameNu.bk\Downloads"
        robocopy "$Source" "$Destn" /e /dcopy:t /xo /xj /MT:100

        $Source = "$DiskNu\Favorites"
        $Destn = "D:\Script test\PC2\$NameNu.bk\Favorites"
        robocopy "$Source" "$Destn" /e /dcopy:t /xo /xj /MT:100

        $Source = "$DiskNu\Desktop"
        $Destn = "D:\Script test\PC2\$NameNu.bk\Desktop"
        robocopy "$Source" "$Destn" /e /dcopy:t /xo /xj /MT:100
    }
    elseif( $NameNu[-1] -eq "4" -or $NameNu[-1] -eq "5") 
    {
        $Source = "$DiskNu\Downloads"
        $Destn = "D:\Script test\PC3\$NameNu.bk\Downloads"
        robocopy "$Source" "$Destn" /e /dcopy:t /xo /xj /MT:100

        $Source = "$DiskNu\Favorites"
        $Destn = "D:\Script test\PC3\$NameNu.bk\Favorites"
        robocopy "$Source" "$Destn" /e /dcopy:t /xo /xj /MT:100

        $Source = "$DiskNu\Desktop"
        $Destn = "D:\Script test\PC3\$NameNu.bk\Desktop"
        robocopy "$Source" "$Destn" /e /dcopy:t /xo /xj /MT:100
    }
    elseif( $NameNu[-1] -eq "6" -or $NameNu[-1] -eq "7") 
    {
        $Source = "$DiskNu\Downloads"
        $Destn = "D:\Script test\PC4\$NameNu.bk\Downloads"
        robocopy "$Source" "$Destn" /e /dcopy:t /xo /xj /MT:100

        $Source = "$DiskNu\Favorites"
        $Destn = "D:\Script test\PC4\$NameNu.bk\Favorites"
        robocopy "$Source" "$Destn" /e /dcopy:t /xo /xj /MT:100

        $Source = "$DiskNu\Desktop"
        $Destn = "D:\Script test\PC4\$NameNu.bk\Desktop"
        robocopy "$Source" "$Destn" /e /dcopy:t /xo /xj /MT:100
    }
    elseif( $NameNu[-1] -eq "8" -or $NameNu[-1] -eq "9") 
    {
        $Source = "$DiskNu\Downloads"
        $Destn = "D:\Script test\PC5\$NameNu.bk\Downloads"
        robocopy "$Source" "$Destn" /e /dcopy:t /xo /xj /MT:100

        $Source = "$DiskNu\Favorites"
        $Destn = "D:\Script test\PC5\$NameNu.bk\Favorites"
        robocopy "$Source" "$Destn" /e /dcopy:t /xo /xj /MT:100

        $Source = "$DiskNu\Desktop"
        $Destn = "D:\Script test\PC5\$NameNu.bk\Desktop"
        robocopy "$Source" "$Destn" /e /dcopy:t /xo /xj /MT:100
    }

Dismount-DiskImage -ImagePath "D:\Script test\Disk\UVHD-$SIDNu.vhdx"
}

我也嘗試過使用「Powershell -c "Path"」的方式了,但因為中間有變數的情況下,又不曉得剛如何將變數值帶過去

看更多先前的討論...收起先前的討論...
froce iT邦大師 1 級 ‧ 2022-09-14 10:34:33 檢舉
https://docs.microsoft.com/zh-tw/powershell/scripting/learn/ps101/09-functions?view=powershell-7.2
踏雪尋梅 iT邦研究生 5 級 ‧ 2022-09-14 10:39:55 檢舉
是的,我也正在寫成函式,也許我這方向是對的!
有些共同指令可以函式化,把指令重用率提升,別差不多的事一直重現
踏雪尋梅 iT邦研究生 5 級 ‧ 2022-09-14 11:10:31 檢舉
japhenchen 是的,我也是這樣想的!
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
3
柳丁柚
iT邦新手 1 級 ‧ 2022-09-14 11:54:29
最佳解答

函數化是對的
我是用字串連接變數的方式
因為沒寫過SHELL 幫你查了大概的用法
https://docs.microsoft.com/zh-tw/powershell/scripting/learn/deep-dives/everything-about-string-substitutions?view=powershell-7.2
希望有幫到你

看更多先前的回應...收起先前的回應...
柳丁柚 iT邦新手 1 級 ‧ 2022-09-14 11:57:06 檢舉

另外可以考慮用switch

踏雪尋梅 iT邦研究生 5 級 ‧ 2022-09-14 14:39:47 檢舉
function Get-Path {
    $DownPath = "Downloads"
    $FavorPath = "Favorites"
    $DeskPath = "Desktop"

    $Source = "$DiskNu\$DownPath"
    $Destn = "D:\Script test\$PCNu\$NameNu.bk\$DownPath"
    robocopy $Source $Destn /e /dcopy:t /xo /xj /MT:100

    $Source = "$DiskNu\$FavorPath"
    $Destn = "D:\Script test\$PCNu\$NameNu.bk\$FavorPath"
    robocopy $Source $Destn /e /dcopy:t /xo /xj /MT:100

    $Source = "$DiskNu\$DeskPath"
    $Destn = "D:\Script test\$PCNu\$NameNu.bk\$DeskPath"
    robocopy $Source $Destn /e /dcopy:t /xo /xj /MT:100
}

for ($i= 0; $i -le 1; $i++){
$SIDNu = (import-Csv "D:\Script test\SID.csv").SID[$i]
$NameNu = (import-Csv "D:\Script test\SID.csv").Name[$i]

Mount-DiskImage -ImagePath "D:\Script test\Disk\UVHD-$SIDNu.vhdx"
$DiskNu = (Get-WmiObject -Class Win32_LogicalDisk -Filter "VolumeName='User Disk'" | Select-Object DeviceID).DeviceID
    
    switch ( $NameNu[-1] )
    {
        0 {$PCNu = "PC1";Get-Path}
        1 {$PCNu = "PC1";Get-Path}
        2 {$PCNu = "PC2";Get-Path}
        3 {$PCNu = "PC2";Get-Path}
        4 {$PCNu = "PC3";Get-Path}
        5 {$PCNu = "PC3";Get-Path}
        6 {$PCNu = "PC4";Get-Path}
        7 {$PCNu = "PC4";Get-Path}
        8 {$PCNu = "PC5";Get-Path}
        9 {$PCNu = "PC5";Get-Path}
    }
Dismount-DiskImage -ImagePath "D:\Script test\Disk\UVHD-$SIDNu.vhdx"
}
踏雪尋梅 iT邦研究生 5 級 ‧ 2022-09-14 14:40:27 檢舉

OK 搞定,感覺這樣濃縮已經很足夠了

踏雪尋梅 iT邦研究生 5 級 ‧ 2022-09-14 14:52:27 檢舉

看起來舒服多了!

柳丁柚 iT邦新手 1 級 ‧ 2022-09-14 16:32:11 檢舉

恭喜

bizpro iT邦大師 1 級 ‧ 2022-09-15 16:39:42 檢舉

建議用參數的方式:

function Get-Path ( [String]$PCNu ) {
    $DownPath = "Downloads"
    $FavorPath = "Favorites"
    $DeskPath = "Desktop"

    $Source = "$DiskNu\$DownPath"
    $Destn = "D:\Script test\$PCNu\$NameNu.bk\$DownPath"
    robocopy $Source $Destn /e /dcopy:t /xo /xj /MT:100

    $Source = "$DiskNu\$FavorPath"
    $Destn = "D:\Script test\$PCNu\$NameNu.bk\$FavorPath"
    robocopy $Source $Destn /e /dcopy:t /xo /xj /MT:100

    $Source = "$DiskNu\$DeskPath"
    $Destn = "D:\Script test\$PCNu\$NameNu.bk\$DeskPath"
    robocopy $Source $Destn /e /dcopy:t /xo /xj /MT:100
}

for ($i= 0; $i -le 1; $i++){
$SIDNu = (import-Csv "D:\Script test\SID.csv").SID[$i]
$NameNu = (import-Csv "D:\Script test\SID.csv").Name[$i]

Mount-DiskImage -ImagePath "D:\Script test\Disk\UVHD-$SIDNu.vhdx"
$DiskNu = (Get-WmiObject -Class Win32_LogicalDisk -Filter "VolumeName='User Disk'" | Select-Object DeviceID).DeviceID
#看起來可以用計算的: 0,1-->1; 2,3-->2,...
Get-Path "PC"+[Math]::Truncate(($NameNu[-1]+2)/2)

Dismount-DiskImage -ImagePath "D:\Script test\Disk\UVHD-$SIDNu.vhdx"
}
0
k761233
iT邦新手 5 級 ‧ 2022-09-15 09:13:52

陣列+sprintf寫成函式,就能簡化

0
暗魂駭客
iT邦新手 5 級 ‧ 2022-09-19 11:43:53

 

我要發表回答

立即登入回答