函数,函数中的变量以及更严格的编码实践

时间:2014-09-30 13:06:32

标签: powershell

我对powershell并不是全新的,只是我的脚本变得越来越复杂,一些概念让我望而却步。我的脚本看起来过长,因为我使用了大量具有可重复部分的函数。看起来我可以在我的函数中的某个地方做变量,但我真的不明白从哪里开始(我一直在寻找)。

此脚本根据添加到Windows虚拟机(2k8r2)的磁盘数量格式化和标记磁盘。我使用了很多函数(脚本工作......通常我停止的地方)...只是我只是想提高我的脚本编写能力。所以最大的问题是如何缩短它?有没有更好的方法来布局和编写我的代码?任何意见,将不胜感激。感谢

#Powershell script to pull info from diskpart and format disks
#Date      : 09/15/2014

Function DISKFORMAT
{NEW-ITEM -Name detail.txt -ItemType file -force | OUT-NULL
ADD-CONTENT -Path detail.txt "SELECT DISK $DISKID"
ADD-CONTENT -Path detail.txt "CREATE PARTITION PRIMARY"
ADD-CONTENT -Path detail.txt "FORMAT FS=NTFS QUICK"
ADD-CONTENT -Path detail.txt "ASSIGN"
$DETAIL=(DISKPART /S detail.txt)}

Function SQLDIR1
{New-Item -Path D:\MSSQL -ItemType directory
New-Item -Path D:\MSSQL\DATA01 -ItemType directory
New-Item -Path D:\MSSQL\TRANS01 -ItemType directory
New-Item -Path D:\MSSQL\LOG01 -ItemType directory
New-Item -Path D:\MSSQL\TEMPDB -ItemType directory}

Function SQLDIR2
{New-Item -Path D:\MSSQL -ItemType directory
New-Item -Path D:\MSSQL\DATA01 -ItemType directory
New-Item -Path D:\MSSQL\TRANS01 -ItemType directory
New-Item -Path D:\MSSQL\LOG01 -ItemType directory
New-Item -Path D:\MSSQL\TEMPDB -ItemType directory
New-Item -Path D:\MSSQL\Backup -ItemType directory}

Function SQLDATA01
{NEW-ITEM -Name detail.txt -ItemType file -force | OUT-NULL
ADD-CONTENT -Path detail.txt "SELECT DISK $DISKID"
ADD-CONTENT -Path detail.txt "CREATE PARTITION PRIMARY"
ADD-CONTENT -Path detail.txt "FORMAT FS=NTFS UNIT=64K QUICK"
ADD-CONTENT -Path detail.txt "ASSIGN MOUNT=D:\MSSQL\DATA01"}

Function SQLTRANS01
{NEW-ITEM -Name detail.txt -ItemType file -force | OUT-NULL
ADD-CONTENT -Path detail.txt "SELECT DISK $DISKID"
ADD-CONTENT -Path detail.txt "CREATE PARTITION PRIMARY"
ADD-CONTENT -Path detail.txt "FORMAT FS=NTFS UNIT=64K QUICK"
ADD-CONTENT -Path detail.txt "ASSIGN MOUNT=D:\MSSQL\TRANS01"}

Function SQLLOG01
{NEW-ITEM -Name detail.txt -ItemType file -force | OUT-NULL
ADD-CONTENT -Path detail.txt "SELECT DISK $DISKID"
ADD-CONTENT -Path detail.txt "CREATE PARTITION PRIMARY"
ADD-CONTENT -Path detail.txt "FORMAT FS=NTFS UNIT=64K QUICK"
ADD-CONTENT -Path detail.txt "ASSIGN MOUNT=D:\MSSQL\LOG01"}

Function SQLTEMPDB
{NEW-ITEM -Name detail.txt -ItemType file -force | OUT-NULL
ADD-CONTENT -Path detail.txt "SELECT DISK $DISKID"
ADD-CONTENT -Path detail.txt "CREATE PARTITION PRIMARY"
ADD-CONTENT -Path detail.txt "FORMAT FS=NTFS UNIT=64K QUICK"
ADD-CONTENT -Path detail.txt "ASSIGN MOUNT=D:\MSSQL\TEMPDB"}

Function SQLBACKUP
{NEW-ITEM -Name detail.txt -ItemType file -force | OUT-NULL
ADD-CONTENT -Path detail.txt "SELECT DISK $DISKID"
ADD-CONTENT -Path detail.txt "CREATE PARTITION PRIMARY"
ADD-CONTENT -Path detail.txt "FORMAT FS=NTFS UNIT=64K QUICK"
ADD-CONTENT -Path detail.txt "ASSIGN MOUNT=D:\MSSQL\Backup"}

Function LABEL1
{$drive = Get-WmiObject -Class win32_volume -Filter "DriveLetter = 'C:'"
    Set-WmiInstance -input $drive -Arguments @{DriveLetter="C:"; Label="OS"}}

Function LABEL2
{$drive = Get-WmiObject -Class win32_volume -Filter "DriveLetter = 'C:'"
    Set-WmiInstance -input $drive -Arguments @{DriveLetter="C:"; Label="OS"}
$drive = Get-WmiObject -Class win32_volume -Filter "DriveLetter = 'D:'"
    Set-WmiInstance -input $drive -Arguments @{DriveLetter="D:"; Label="Data"}}

Function LABEL3
{$drive = Get-WmiObject -Class win32_volume -Filter "DriveLetter = 'C:'"
    Set-WmiInstance -input $drive -Arguments @{DriveLetter="C:"; Label="OS"}
$drive = Get-WmiObject -Class win32_volume -Filter "DriveLetter = 'D:'"
    Set-WmiInstance -input $drive -Arguments @{DriveLetter="D:"; Label="Apps"}
$drive = Get-WmiObject -Class win32_volume -Filter "DriveLetter = 'E:'"
    Set-WmiInstance -input $drive -Arguments @{DriveLetter="E:"; Label="Data"}}

Function LABEL4
{$drive = Get-WmiObject -Class win32_volume -Filter "DriveLetter = 'C:'"
    Set-WmiInstance -input $drive -Arguments @{DriveLetter="C:"; Label="OS"}
$drive = Get-WmiObject -Class win32_volume -Filter "DriveLetter = 'D:'"
    Set-WmiInstance -input $drive -Arguments @{DriveLetter="D:"; Label="Apps"}
$drive = Get-WmiObject -Class win32_volume -Filter "DriveLetter = 'E:'"
    Set-WmiInstance -input $drive -Arguments @{DriveLetter="E:"; Label="Data"}
$drive = Get-WmiObject -Class win32_volume -Filter "DriveLetter = 'F:'"
    Set-WmiInstance -input $drive -Arguments @{DriveLetter="F:"; Label="Data01"}}

# List All disks
NEW-ITEM –name listdisk.txt –itemtype file –force | OUT-NULL
ADD-CONTENT –path listdisk.txt "LIST DISK"
$LISTDISK=(DISKPART /S listdisk.txt)
$TOTALDISK=($LISTDISK.Count)-7

#If there's only one disk (OS DISK) Exit the script
IF ($TOTALDISK -eq 1)
{LABEL1}

IF ($TOTALDISK -eq 2)
{$DISKID=$LISTDISK[8].substring(7,5).trim()
DISKFORMAT
LABEL2}

IF ($TOTALDISK -eq 3)
{$DISKID=$LISTDISK[8].substring(7,5).trim()
DISKFORMAT
$DISKID=$LISTDISK[9].substring(7,5).trim()
DISKFORMAT
LABEL3}

IF ($TOTALDISK -eq 4)
{$DISKID=$LISTDISK[8].substring(7,5).trim()
DISKFORMAT
$DISKID=$LISTDISK[9].substring(7,5).trim()
DISKFORMAT
$DISKID=$LISTDISK[10].substring(7,5).trim()
DISKFORMAT
LABEL4}

IF ($TOTALDISK -eq 5)
{$DISKID=$LISTDISK[8].substring(7,5).trim()
DISKFORMAT
LABEL2
SQLDIR1
SQLDATA01
SQLTRANS01
SQLLOG01
SQLTEMPDB}

IF ($TOTALDISK -eq 6)
{$DISKID=$LISTDISK[8].substring(7,5).trim()
DISKFORMAT
LABEL2
SQLDIR2
SQLDATA01
SQLTRANS01
SQLLOG01
SQLTEMPDB
SQLBACKUP}


ELSE {EXIT}

3 个答案:

答案 0 :(得分:0)

您可以尝试避免使用命令重复,如下所示。

New-Item -Path D:\MSSQL,D:\MSSQL\DATA01,D:\MSSQL\TRANS01,D:\MSSQL\LOG01,D:\MSSQL\TEMPDB -ItemType directory
ADD-CONTENT -Path detail.txt "SELECT DISK $DISKID", "CREATE PARTITION PRIMARY","FORMAT FS=NTFS UNIT=64K QUICK","ASSIGN MOUNT=D:\MSSQL\Backup"

这会缩小你的脚本。

在LABEL2,LABEL3等中重复LABEL1的功能......

你可以把它写成

Function LABEL1
{
Operation1
}

Function LABEL2
{
;call LABEL1
Operation2
}

Function LABEL3
{
; call LABEL2
Operation3
}

如果没有多次使用,则无需创建函数。使用顺序脚本并使用注释划分。 或者使用参数编写函数并根据某些输入参数执行操作。

答案 1 :(得分:0)

SQLTEMPDB 和类似的功能。

对于初学者我知道你可以整合这样的功能,因为唯一改变的是路径。

Function SQLTEMPDB
{NEW-ITEM -Name detail.txt -ItemType file -force | OUT-NULL
ADD-CONTENT -Path detail.txt "SELECT DISK $DISKID"
ADD-CONTENT -Path detail.txt "CREATE PARTITION PRIMARY"
ADD-CONTENT -Path detail.txt "FORMAT FS=NTFS UNIT=64K QUICK"
ADD-CONTENT -Path detail.txt "ASSIGN MOUNT=D:\MSSQL\TEMPDB"}

使用路径参数可以将其更改为此参数以将其减少为一个函数。同时将对Add-Content的调用减少到一个。用户一个Here-String并根据需要添加一个路径。

Function Add-FormatDetail{
param($Path)
NEW-ITEM -Name detail.txt -ItemType file -force | OUT-NULL
$details = @"
SELECT DISK $DISKID
CREATE PARTITION PRIMARY
FORMAT FS=NTFS UNIT=64K QUICK
ASSIGN MOUNT=$Path
"@
Add-Content -Path detail.txt -Value $details
}

例如,您可以调用以下

代替被叫SQLTEMPDB
Add-FormatDetail -Path "D:\MSSQL\TEMPDB"

标签功能也可以合并。一个简单的(绝不是优雅的)解决方案将再次制作一个以$ driveCount作为参数的函数。

Function Update-DriveLabels{
    param([int]$driveCount)
    If ($driveCount -gt 0){
        $drive = Get-WmiObject -Class win32_volume -Filter "DriveLetter = 'C:'"
            Set-WmiInstance -input $drive -Arguments @{DriveLetter="C:"; Label="OS"}
    }
    If ($driveCount -gt 1){
        $drive = Get-WmiObject -Class win32_volume -Filter "DriveLetter = 'D:'"
            Set-WmiInstance -input $drive -Arguments @{DriveLetter="D:"; Label="Apps"}
    }
    If ($driveCount -gt 2){
        $drive = Get-WmiObject -Class win32_volume -Filter "DriveLetter = 'E:'"
            Set-WmiInstance -input $drive -Arguments @{DriveLetter="E:"; Label="Data"}
    }
    If ($driveCount -gt 3){
    $drive = Get-WmiObject -Class win32_volume -Filter "DriveLetter = 'F:'"
        Set-WmiInstance -input $drive -Arguments @{DriveLetter="F:"; Label="Data01"}
    }
} 

所以调用将在你的脚本中

Update-DriveLabels -DriveCount $TOTALDISK

答案 2 :(得分:0)

@Matt感谢您的评论,这非常有帮助。

只有一个小问题。在标签部分,如果没有磁盘则会出错。我应该退出还是有更好的方法呢?

这是最终的工作脚本(编辑:在SQL团队请求其他配置后更新了脚本):

#set the path variable
$folder="D:\MSSQL\"

#Function to Format Disks using diskpart
Function DISKFORMAT
{NEW-ITEM -Name detail.txt -ItemType file -force | OUT-NULL
ADD-CONTENT -Path detail.txt "SELECT DISK $DISKID"
ADD-CONTENT -Path detail.txt "CREATE PARTITION PRIMARY"
ADD-CONTENT -Path detail.txt "FORMAT FS=NTFS QUICK"
ADD-CONTENT -Path detail.txt "ASSIGN"
$DETAIL=(DISKPART /S detail.txt)}

#Function to format disks for SQL
Function Add-FormatDetail{
param($Path)
NEW-ITEM -Name detail1.txt -ItemType file -force | OUT-NULL
$details = @"
SELECT DISK $DISKID
CREATE PARTITION PRIMARY
FORMAT FS=NTFS LABEL=$Path UNIT=64K QUICK
ASSIGN MOUNT=$Folder$Path
"@
Add-Content -Path detail1.txt -Value $details
$DETAIL=(DISKPART /S detail1.txt)}

#Function to automatically label all disks other than SQL
Function Update-DriveLabels{
    param([int]$driveCount)
    If ($driveCount -gt 0){
        $drive = Get-WmiObject -Class win32_volume -Filter "DriveLetter = 'C:'"
            Set-WmiInstance -input $drive -Arguments @{DriveLetter="C:"; Label="OS"}
    }
    If ($driveCount -gt 1){
        $drive = Get-WmiObject -Class win32_volume -Filter "DriveLetter = 'D:'"
            Set-WmiInstance -input $drive -Arguments @{DriveLetter="D:"; Label="Apps"}
    }
    If ($driveCount -gt 2){
        $drive = Get-WmiObject -Class win32_volume -Filter "DriveLetter = 'E:'"
            Set-WmiInstance -input $drive -Arguments @{DriveLetter="E:"; Label="Data"}
    }
    If ($driveCount -gt 3){
    $drive = Get-WmiObject -Class win32_volume -Filter "DriveLetter = 'F:'"
        Set-WmiInstance -input $drive -Arguments @{DriveLetter="F:"; Label="Data01"}
    }
} 

# List All disks
NEW-ITEM –name listdisk.txt –itemtype file –force | OUT-NULL
ADD-CONTENT –path listdisk.txt "LIST DISK"
$LISTDISK=(DISKPART /S listdisk.txt)
$TOTALDISK=($LISTDISK.Count)-7

IF ($TOTALDISK -eq 2)
{$DISKID=$LISTDISK[8].substring(7,5).trim()
DISKFORMAT}

IF ($TOTALDISK -eq 3) 
{$DISKID=$LISTDISK[8].substring(7,5).trim()
DISKFORMAT
$DISKID=$LISTDISK[9].substring(7,5).trim()
DISKFORMAT}

IF ($TOTALDISK -eq 4) 
{$DISKID=$LISTDISK[8].substring(7,5).trim()
DISKFORMAT
$DISKID=$LISTDISK[9].substring(7,5).trim()
DISKFORMAT
$DISKID=$LISTDISK[10].substring(7,5).trim()
DISKFORMAT}

IF ($TOTALDISK -eq 5) 
{$DISKID=$LISTDISK[8].substring(7,5).trim()
DISKFORMAT
$DISKID=$LISTDISK[9].substring(7,5).trim()
DISKFORMAT
$DISKID=$LISTDISK[10].substring(7,5).trim()
DISKFORMAT
$DISKID=$LISTDISK[11].substring(7,5).trim()
DISKFORMAT}

IF ($TOTALDISK -eq 6) 
{$DISKID=$LISTDISK[8].substring(7,5).trim()
DISKFORMAT 
New-Item -Path $folder,$folder"DATA01",$folder"TRANS01",$folder"TEMPDB",$folder"Backup" -ItemType directory
$DISKID=$LISTDISK[9].substring(7,5).trim()
Add-FormatDetail -Path "DATA01"
$DISKID=$LISTDISK[10].substring(7,5).trim()
Add-FormatDetail -Path "TRANS01"
$DISKID=$LISTDISK[11].substring(7,5).trim()
Add-FormatDetail -Path "TEMPDB"
$DISKID=$LISTDISK[12].substring(7,5).trim()
Add-FormatDetail -Path "Backup"}

IF ($TOTALDISK -eq 10) 
{$DISKID=$LISTDISK[8].substring(7,5).trim()
DISKFORMAT 
New-Item -Path $folder,$folder"DATA01",$folder"TRANS01",$folder"TEMPDB",$folder"Backup" -ItemType directory
New-Item -Path $folder"DATA02",$folder"TRANS02",$folder"TEMPDB2",$folder"Backup2" -ItemType directory
$DISKID=$LISTDISK[9].substring(7,5).trim()
Add-FormatDetail -Path "DATA01"
$DISKID=$LISTDISK[10].substring(7,5).trim()
Add-FormatDetail -Path "TRANS01"
$DISKID=$LISTDISK[11].substring(7,5).trim()
Add-FormatDetail -Path "TEMPDB"
$DISKID=$LISTDISK[12].substring(7,5).trim()
Add-FormatDetail -Path "Backup"
$DISKID=$LISTDISK[13].substring(7,5).trim()
Add-FormatDetail -Path "DATA02"
$DISKID=$LISTDISK[14].substring(7,5).trim()
Add-FormatDetail -Path "TRANS02"
$DISKID=$LISTDISK[15].substring(7,5).trim()
Add-FormatDetail -Path "TEMPDB2"
$DISKID=$LISTDISK[16].substring(7,5).trim()
Add-FormatDetail -Path "Backup2"}

Update-DriveLabels -DriveCount $TOTALDISK