Copy and
paste the below into a text editor and save as say CS7C.ps1.
###############################
## CIFS_Shares_7_to_C (CS7C)
##
###############################
# The program can run run
simply as .\CS7C.ps1.
# The following parameters
are not necessary to run CS7C.
# You need to construct the
VolsToMigrate file first.
Param(
# (NO PROMPT) Version:
[String]$Version = "1.0",
# Clustername / Cluster Mgmt IP:
[String]$Cluster,
# SVM Name:
[String]$SVM,
# Specifies whether volume names are changing
going to CDOT:
[Switch]$VolNameChange,
[Switch]$NoVolNameChange,
# (NO PROMPT) File path to file containing 7
to C volume name mappings:
[String]$VolMappingFilePath =
"CS7C.VolNameMap.TXT",
# (NO PROMPT) File path to file containing
7-Mode volumes to migrate:
[String]$VolsToMigrateFilePath =
"CS7C.VolsToMigrate.TXT",
# The workstation is either ON / OFF the
domain used by source 7-Mode CIFS server:
[Switch]$OnDomain,
[Switch]$OffDomain,
# (NO PROMPT) If running from a machine off
domain you need to provide this:
[String]$SIDtoNameMapFilePath =
"CS7C.SIDtoNameMap.TXT",
# (NO PROMPT) This file contains the list of
CDOT Shares on the SVM:
[String]$CDOTSVMsharesFilePath =
"CS7C.CdotVserverShares.TXT",
# Do CDOT volume junctions paths have /vol or
just /?:
[Switch]$SlashVol,
[Switch]$NoSlashVol,
# (NO PROMPT) CIFS Share Property Standards:
[String]$OfflineFiles = "manual",
[String]$ShareProperties =
"browsable,oplocks,changenotify",
[String]$SymlinkProperties =
"symlinks",
[String]$VscanFileopProfile =
"standard",
# (NO PROMPT) CLI only switch to add _FILER to
the CIFS share name:
[Switch]$AppendFilerNameToShare,
# Output Filename Prefix:
[String]$OutputFilePrefix,
# You can specify $INIfile if you want run
from an INI file:
[String]$INIfile,
# INTERNAL SWITCH!:
[Switch]$InvokedByINIfile
)
## BASIC DISPLAY FUNCTIONS /
GENERIC FUNCTIONS ##
##
=========================================== ##
FUNCTION
Uline{$args[0];("## " + "".PadRight($args[0].length
-6,"=") + " ##");""}
FUNCTION Wr {
Param([String]$ToDisplay,[String]$Color =
"WHITE")
If($ToDisplay){
Write-Host $ToDisplay -ForegroundColor $Color
-NoNewLine
}else{
Write-Host
}
}
FUNCTION Columnize {
For($i = 0; $i -lt $args.count; $i += 3){
If($i -lt ($args.count - 3)){
Wr ($args[$i].PadRight($args[$i+1],"
").SubString(0,$args[$i+1])) ($args[$i+2])
}else{
Wr ($args[$i]) -Color ($args[$i+2]);Wr
}
}
}
FUNCTION Press-Enter{Wr
"Press Enter to continue... " CYAN;$P = Read-Host}
FUNCTION EXITING{Wr " -
exiting!" RED;Wr;Wr;Press-Enter;EXIT}
FUNCTION PromptValidator{
Param([Switch]$YesOrNo)
while ($TRUE){
$ReadIn = Read-Host
If ($YesOrNo){
If(($ReadIn -eq "YES") -or
($ReadIn -eq "Y")){
RETURN $True
}
If(($ReadIn -eq "NO") -or ($ReadIn -eq "N")){
RETURN $False
}
}ELSEIF($args[0]){
Foreach($argument in $args){
If($ReadIn -eq $argument){
RETURN $ReadIn
}
}
}ELSE{
If($ReadIn.length -ge 1){RETURN $ReadIn}
}
}
}
FUNCTION PromptSetting {
Param([String]$Prompt,[String]$Setting,[Switch]$AllowEnter)
Wr $Prompt CYAN
If($Setting){
Wr $Setting;Wr;RETURN $Setting
}
If($AllowEnter){
$NewSetting = Read-Host;RETURN $NewSetting
}
Return (PromptValidator)
}
FUNCTION ProcessYesNoSwitch
{
Param([String]$Question,[Boolean]$EnableSwitch,[Boolean]$DisableSwitch)
Wr $Question CYAN
If($EnableSwitch){
Wr "YES";Wr;RETURN $true
}elseif($DisableSwitch){
Wr "NO";Wr;RETURN $false
}else{
PromptValidator -YesOrNo
}
}
FUNCTION ProcessArray {
Param([System.Array]$ArrayToProcess,[Switch]$AllowHash)
[System.Array]$ProcessedArray = @()
Foreach($ArrayLine in $ArrayToProcess){
If($ArrayLine -ne ""){
If($ArrayLine.substring(0,1) -ne
"#"){
If($AllowHash){
$ProcessedArray += $ArrayLine
}else{
$ProcessedArray +=
$ArrayLine.Split("#")[0].Trim()
}
}
}
}
, $ProcessedArray
}
FUNCTION
Process7MMTinputFile {
Param([String]$InputFile,[String]$Description,[Switch]$AllowHash)
If(!(Test-Path $InputFile)){
Wr "$Description specified but path test
to $InputFile failed" RED;EXITING
}
[System.Array]$GetFile = Get-Content
$InputFile
If(!$GetFile){
Wr "$Description specified but file
$InputFile is empty!" RED;Wr;Wr
}
Wr "Loaded $Description from $InputFile
successfully!" GREEN;Wr
If($AllowHash){
$GetFile = ProcessArray $GetFile -AllowHash
}else{
$GetFile = ProcessArray $GetFile
}
, $GetFile
}
## IF HAVE INI FILE ##
## ================ ##
If($INIfile -and
!$InvokedByINIfile){
If (!(Test-Path $INIfile)){
Wr;Wr "INI file $INIfile specified but
not detected!" RED;Wr;Wr;EXIT
}
$INIcontent = Get-Content $INIfile
$INIcontent = ProcessArray $INIcontent
[String]$CommandExpression = ""
$INIcontent | foreach{
If($_.split("=").count -ge 2){
$CommandExpression +=
((($_.split("="))[0]).trim() + " " +
(($_.split("="))[1]).trim() + " ")
}else{
$CommandExpression += $_.trim() + "
"
}
}
Cls;Wr;Wr "Detected $INIfile and
running:" MAGENTA;Wr
Wr;Wr $commandExpression;Wr;Wr
Invoke-Expression ($CommandExpression + "
-InvokedByINIfile")
EXIT
}elseif(!$InvokedByINIfile){
Wr;Wr "-INIfile not specified: not
running from an INI File" CYAN;Wr
}
## CONNECT TO 7-MODE/CDOT
CLUSTER FUNCTION ##
##
======================================= ##
FUNCTION Get-PsCredential{
Param([String]$Username,[String]$PasswordPrompt)
Wr $PasswordPrompt CYAN;$Password = Read-Host
-AsSecureString;Wr
RETURN (New-Object
System.Management.Automation.PsCredential($Username,$Password))
}
FUNCTION Load-DataOntapPSTK
{
If(Get-Module DataONTAP){RETURN}
[Void](Import-Module DataONTAP -ErrorAction
SilentlyContinue)
If(!(Get-Module DataONTAP)){
Wr "Unable to load the DataONTAP
PowerShell Toolkit" RED;EXITING
}
Wr "Loaded the Data ONTAP PowerShell
Toolkit!" GREEN;Wr;Wr
}
FUNCTION Connect-ToNetApp {
Param([String]$System,[System.Object]$Creds,[Switch]$SevenMode)
# Note: The default is cDOT
[Void](Load-DataOntapPSTK)
Wr "Checking connection to $System
..." CYAN; Wr
If($SevenMode){
$Connected = Connect-NaController -Name
$System -Credential $Creds -Timeout 20000 -ErrorAction SilentlyContinue
}else{
$Connected = Connect-NcController -Name
$System -Credential $Creds -Timeout 20000 -ErrorAction SilentlyContinue
}
If($Connected){
Wr "Successfully connected to
$System" GREEN;Wr;Wr
}else{
Wr "Unable to connect to $System with
provided credentials" RED;EXITING
}
}
#############################
## PART 1: DATA COLLECTION
##
#############################
Wr;Wr
"<<<<<<<<<< CS7C: $Version
>>>>>>>>>>" MAGENTA;Wr;Wr
$OutputFilePrefix =
PromptSetting "Output File Prefix? " $OutputFilePrefix
$OutputFileName =
$OutputFilePrefix + "_CIFS_SHARES.txt"
Wr;Wr
">>>>>>> PART 1: DATA COLLECTION
<<<<<<<" MAGENTA;Wr;Wr
## MAPPING 7-MODE VOLUMES TO
CDOT VOLUMES ##
##
====================================== ##
[System.Array]$Systems7G = @()
[System.Object]$7ModeVol = @{}
[System.Object]$CutoverVols = @{}
[System.Object]$MapVols = @{}
[System.Array]$CdotVolsArray
= @()
[String]$CdotVolsList = ""
[System.Object]$vFilerList = @{}
$VolNameChange =
ProcessYesNoSwitch "Are volume names changing going to CDOT (yes/no)?
" $VolNameChange $NoVolNameChange;Wr
If($VolNameChange){
[System.Array]$VolMap = Process7MMTinputFile
$VolMappingFilePath "7CGT 7-C Volume Name Mapping File"
}
[System.Array]$VolsToMigrate
= Process7MMTinputFile $VolsToMigrateFilePath "Volumes to Migrate from
7-Mode File"
## PROCESS THE VOLUMES TO
MIGRATE FILE ##
Foreach ($line in
$VolsToMigrate){
$lineSplit = $line.split(",")
If(($lineSplit.count -eq 3) -or
($lineSplit.count -eq 4)){
$pFiler = $lineSplit[0]
If(!($Systems7G -contains $pFiler)){
$Systems7G += $pFiler
[System.Object]$7ModeVol.$pFiler = @{}
[System.Object]$CutoverVols.$pFiler = @{}
[System.Array]$CutoverVols.$pFiler.VOLs7 =
@()
}
$Volume7G = $lineSplit[2]
$7ModeVol.$pFiler.$Volume7G = $lineSplit[1]
$CutoverVols.$pFiler.VOLs7 += $Volume7G
If(!$Volume7G){
Wr;Wr "Error processing Vols to Migrate
File and this line - " RED;Wr;Wr $line YELLOW;EXITING
}
}
}
If(!$Systems7G){
Wr;Wr "Error processing the Vols To
Migrate file $VolsToMigrateFilePath" RED;EXITING
}
## PROCESS 7-MODE TO CDOT
VOLUME NAME CHANGES ##
$Systems7G | Foreach {
[System.Array]$CutoverVols.$_.VOLsC = @()
If($VolNameChange){
Foreach($vol7G in $CutoverVols.$_.VOLs7){
$FoundMatch = $null
Foreach($line in $VolMap){
$lineSplit = $line.split(",")
If($lineSplit[0] -eq $_){
If($lineSplit[1] -eq $vol7G){
$FoundMatch = $true
If($lineSplit.count -gt 2){
$CutoverVols.$_.VOLsC += $lineSplit[2]
}else{
$CutoverVols.$_.VOLsC += $lineSplit[1]
}
}
}
}
If(!$FoundMatch){Wr "Unable to find a
match for volume $vol7G in $VolMappingFilePath" RED;EXITING}
}
}else{
$CutoverVols.$_.VOLsC = $CutoverVols.$_.VOLs7
}
}
## OUTPUT TO 7-MODE VOLS TO
CDOT VOLS TABLE ##
Wr;Wr ">>>
MAPPING 7-MODE VOLUMES TO CDOT VOLUMES <<<" GREEN;Wr;Wr
Columnize "7-MODE
SYSTEM" 25 Green "OWNING VFILER" 25 Green "VOLUME
(7G)" 25 Green "VOLUME (CDOT)" 30 Green
$j = 0
$Systems7G | Foreach {
$j++;$i = 0
[System.Object]$MapVols.$_ = @{}
[System.Object]$vFilerList.$_ = @{}
[System.Array]$vFilerList.$_.vFilers = @()
$CdotVolsArray += $CutoverVols.$_.VOLsC
Foreach($vol7G in ($CutoverVols.$_.VOLs7)){
$volCM = ($CutoverVols.$_.VOLsC)[$i]
$MapVols.$_.$vol7G = $volCM
$OwningVfiler = $7ModeVol.$_.$vol7G
Columnize $_ 25 Cyan $OwningVfiler 25 Cyan
$vol7G 25 Yellow $volCM 30 Yellow
## THIS SECTION CONSTRUCTS VFILERLIST ##
If($OwningVfiler){
If($vFilerList.$_.$OwningVfiler -eq $null){
[System.Array]$vFilerList.$_.vFilers +=
$OwningVfiler
[System.Array]$vFilerList.$_.$OwningVfiler = @()
$vFilerList.$_.$OwningVfiler += $vol7G
}else{
$vFilerList.$_.$OwningVfiler += $vol7G
}
};$i++
## THIS LINE CONSTRUCTS A COMMA SEPARATED
STRING OF CDOT VOLS ##
If(($i -eq $CutoverVols.$_.VOLs7.count) -and
($j -eq $Systems7G.count)){
$CdotVolsList += $volCM
}else{
$CdotVolsList += $volCM + ","
}
}
}
FUNCTION Get-7MConfigFile{
Param([String]$ETCPATH,[String]$7MConfigFile,[String]$ConfigDirectory)
Wr "Reading the file: " GREEN; Wr
$7MConfigFile; Wr
[String]$ConfigFilePath = $ETCPATH +
"/$7MConfigFile"
[String]$StringOutput = Read-NaFile
$ConfigFilePath
[System.Array]$ArrayOutput =
$StringOutput.Split("`n")
$ArrayOutput | Set-Content ($ConfigDirectory +
"/" + $7MConfigFile)
}
## 7-Mode: ONLINE MODE ##
## =================== ##
Wr;[Boolean]$OnlineFor7Mode
= ProcessYesNoSwitch "Online acquisition of 7-Mode Config Files (yes/no)?
";Wr
If($OnlineFor7Mode){
$UserName7Mode = PromptSetting "7-Mode
Username: "
$Credential7M
= Get-PsCredential $UserName7Mode "7-Mode Password: "
$Systems7G | Foreach{
[Void](Connect-ToNetApp $_ $Credential7M
-SevenMode)
Foreach($vFiler in $vFilerList.$_.vFilers){
[String]$GetRootVol = ""
[String]$ETCPATH = ""
[String]$ConfigDirectory = ($_ +
"." + $vFiler)
[Void](New-Item -Path $ConfigDirectory
-ItemType Directory -Force)
If($vFiler -eq "vFiler0"){
$global:CurrentNaController.vfiler =
""
}else{
$global:CurrentNaController.vfiler =
$vFiler
}
$GetRootVol = (Get-NaVolRoot -ErrorAction
SilentlyContinue).Name
If($GetRootVol){
$ETCPATH = "/vol/" + $GetRootVol
+ "/etc"
}else{
$ETCPATH = (Get-NaCifsShare -Share
ETC$).MountPoint
}
If(!$ETCPATH){
Wr;Wr "$UserName7Mode has permission
issues getting $_ $vFiler 's /etc path, recommend use root" RED;EXITING
}
Wr "ETC path for 7GSystem = $_ &
vFiler = $vFiler is " GREEN;Wr $ETCPATH YELLOW;Wr
[Void](Get-7MConfigFile $ETCPATH
"cifsconfig_share.cfg" $ConfigDirectory)
}
}
}
## PRIMARY CDOT CLUSTER
& SVM ##
##
========================== ##
Wr;Wr ">>>
PRIMARY cDOT CLUSTER & SVM <<<" GREEN;Wr;Wr
$Cluster = PromptSetting
"Enter the Cluster: " $Cluster
$SVM = PromptSetting "Enter the SVM : " $SVM; Wr
[Boolean]$OnlineForCDOT =
ProcessYesNoSwitch "Online cDOT data acquisition (yes/no)? "; Wr
If($OnlineForCDOT){
$UserNameCdot = PromptSetting "Cluster
Username: "
$Credential
= Get-PsCredential $UserNameCdot "Cluster Password: "
[Void](Connect-ToNetApp $Cluster $Credential)
}
## CIFS SHARE SETTINGS ##
## =================== ##
Wr; Wr ">>>
COMMON (STANDARD) CIFS SHARE SETTINGS <<<" GREEN;Wr;Wr
$SlashVol =
ProcessYesNoSwitch "Are volumes mounted with /vol in the CDOT Junction Path
(yes/no)? " $SlashVol $NoSlashVol;Wr
Wr; Wr ">>>
CIFS SHARE SETTING STANDARDS <<<" GREEN;Wr;Wr
Wr "These share
settings are applied to all shares:" GREEN;Wr;Wr
Wr "CIFS Share
Property: OfflineFiles = "
CYAN;Wr $OfflineFiles;Wr
Wr "CIFS Share Property:
ShareProperties = " CYAN;Wr
$ShareProperties;Wr
Wr "CIFS Share
Property: SymlinkProperties = "
CYAN;Wr $SymlinkProperties;Wr
Wr "CIFS Share
Property: VscanFileopProfile = " CYAN;Wr $VscanFileopProfile;Wr;Wr
Wr "The following
settings adopt default values:" GREEN; Wr
Wr "-file-umask /
-dir-umask / -attribute-cache-ttl" CYAN; Wr
## TRANSLATING SIDS TO
USERS/GROUPS ##
##
================================ ##
Wr;Wr ">>>
TRANSLATING SIDS TO USERS/GROUPS <<<" GREEN;Wr;Wr
Wr "To translate SIDs
used in the 7-Mode cifsconfig_share.cfg files to Domain User/Group Names used
in CDOT, we need either a SID to Name Mapping File, or - if the machine we're
running 7CGT on is on the same domain as the systems being transitioned - we
can obtain SIDs using Powershell." GREEN;Wr;Wr
$OnDomain =
ProcessYesNoSwitch "Is this workstation on the same Domain as the systems
being transitioned (yes/no)? " $OnDomain $OffDomain
If(!$OnDomain){
[System.Array]$SIDtoNameMap =
Process7MMTinputFile $SIDtoNameMapFilePath
"SID to Name Map File"
}
[System.Array]$Global:SIDMapFileContent
= @()
$Global:SIDMapFileContent +=
"## SIDMAPFILE"
$Global:SIDMapFileContent +=
"## Setup file with on each row: SID,USERorGROUP"
## CIFS: GET LIST OF SHARES
ON THE CDOT SVM (NEED TO PREVENT CONFLICTS) ##
##
==================================================================== ##
[System.Array]$CifsSharesSVM
= @()
Wr; Wr ">>>
CIFS SHARES ON $SVM <<<" GREEN; Wr; Wr
If($OnlineForCDOT){
$attrs = Get-NcCifsShare -Template
$GetNcCifsShares = Get-NcCifsShare
-VserverContext $SVM -Attributes $attrs
$GetNcCifsShares | Foreach {
$CifsSharesSVM += $_.ShareName
}
[System.Array]$CreateCDOTSharesFile = @()
Foreach($Share in $CifsSharesSVM){
$CreateCDOTSharesFile += ($SVM + ',' + $Share
+ ',')
}
$CreateCDOTSharesFile | Set-Content
$CDOTSVMsharesFilePath
}else{
Wr "Create the CDOT Shares File by
running -" GREEN;Wr
Wr ("$Cluster" + "::>
") GREEN; Wr ("set -showseparator " + '"' + "," +
'"'+ "; rows 0; cifs share show -fields share-name -vserver
$SVM") YELLOW;Wr
Wr "- and then copy and paste this
information into a text file." GREEN;Wr;Wr
[System.Array]$CDOTSharesFile =
Process7MMTinputFile $CDOTSVMsharesFilePath "CDOT SVM Shares File"
-AllowHash;Wr
$CDOTSharesFile | Foreach {
$CifsSharesSVM += $_.Split(",")[1]
}
}
$CifsSharesSVM | Foreach {
Wr $_ YELLOW;Wr
}
## FUNCTION: COLLECT
REQUIRED 7G CONFIG FILES (works on a per vFiler basis) ##
##
======================================================================== ##
FUNCTION GetConfigFile {
Param([String]$7GcfgFile,[String]$7GSystem,[String]$vFilerName)
Wr ("Looking for $7GcfgFile for $7Gsystem
& $vFilerName") GREEN;Wr
Wr (" in this folder ") GREEN;Wr
($7Gsystem + "." + $vFilerName) YELLOW;If($vFilerName -eq
"vFiler0"){Wr " or " GREEN;Wr $7Gsystem YELLOW};Wr
If(Test-Path ($7Gsystem + "." +
$vFilerName + "\" + $7GcfgFile)){
$ArrayOutput = Get-Content ($7Gsystem +
"." + $vFilerName + "\" + $7GcfgFile)
}elseif(($vFilerName -eq "vFiler0")
-and ( Test-Path ($7Gsystem + "\" + $7GcfgFile))){
$ArrayOutput = Get-Content ($7Gsystem +
"\" + $7GcfgFile)
}else{
Wr "Unable to find file"
RED;EXITING
}
If(!$ArrayOutput){
Wr "$7GcfgFile file at $cfgFilePath is a
blank file!" YELLOW;Wr;Wr
}
, $ArrayOutput
}
## FUNCTIONS FOR PROCESSING
CIFS SHARES ##
##
==================================== ##
[System.Object]$CifsCfg =
@{} # CifsCfg hashtable structure:
# OBJECT
$CifsCfg.$System7G.$vFiler
# ARRAY $CifsCfg.$System7G.$vFiler.Volumes
# OBJECT
$CifsCfg.$System7G.$vFiler.ShareToVolume
# STRING
$CifsCfg.$System7G.$vFiler.ShareToVolume.$Share
# OBJECT
$CifsCfg.$System7G.$vFiler.$Volume
# ARRAY $CifsCfg.$System7G.$vFiler.$Volume.Shares
# OBJECT $CifsCfg.$System7G.$vFiler.$Volume.$Sharename
# STRING
$CifsCfg.$System7G.$vFiler.$Volume.$Sharename.ShareName
# STRING
$CifsCfg.$System7G.$vFiler.$Volume.$Sharename.SharePath
# STRING
$CifsCfg.$System7G.$vFiler.$Volume.$Sharename.PathAfterVolume
# STRING $CifsCfg.$System7G.$vFiler.$Volume.$Sharename.Comment
# INT
$CifsCfg.$System7G.$vFiler.$Volume.$Sharename.AccessRules
# STRING
$CifsCfg.$System7G.$vFiler.$Volume.$Sharename.X.UserOrGroup
# STRING
$CifsCfg.$System7G.$vFiler.$Volume.$Sharename.X.Permission
FUNCTION
Process-CifsShareAddLine {
## MANIPULATION: Manipulation of $line ##
$splitLineQuotes = $line.split('"')
If(($splitLineQuotes.count) -ne 7){
Wr ("This line >>> $line
<<< does not have the expected number of quotes (6)!")
RED;Wr;RETURN
}
[String]$Share = $splitLineQuotes[1]
[String]$SharePath = $splitLineQuotes[3]
[String]$comment = $splitLineQuotes[5]
## MANIPULATION: Mainpulate $SharePath to get
$Vol7G,$PathAfterVolName ##
$SplitSharePath =
$SharePath.Split("/")
If ($SharePath -eq "/"){
$Vol7G = "/"
$PathAfterVolName = ""
}elseif($SharePath -eq "/etc"){
$Vol7G = "/"
$PathAfterVolName = "etc"
}else{
$Vol7G = $SplitSharePath[2]
$VolChars = $Vol7G.Length
$PathAfterVolName = $SharePath.Substring((5 +
$VolChars),($SharePath.Length - 5 - $VolChars))
}
## CONSTRUCTION: Construct
$CifsCfg.$System7G.$vFiler ##
If(!($CifsCfg.$System7G.$vFiler.Volumes
-Contains $Vol7G)){
$CifsCfg.$System7G.$vFiler.Volumes += $Vol7G
[System.Object]$CifsCfg.$System7G.$vFiler.$Vol7G = @{}
[System.Array]$CifsCfg.$System7G.$vFiler.$Vol7G.Shares = @()
[Int]$CifsCfg.$System7G.$vFiler.$Vol7G.SharesCount = 0
}
[String]$CifsCfg.$System7G.$vFiler.ShareToVolume.$Share
= $Vol7G
$CifsCfg.$System7G.$vFiler.$Vol7G.Shares +=
$share
[System.Object]$CifsCfg.$System7G.$vFiler.$Vol7G.$Share
= @{}
[String]$CifsCfg.$System7G.$vFiler.$Vol7G.$Share.ShareName
= $Share
[String]$CifsCfg.$System7G.$vFiler.$Vol7G.$Share.SharePath
= $SharePath
[String]$CifsCfg.$System7G.$vFiler.$Vol7G.$Share.PathAfterVolume
= $PathAfterVolName
[String]$CifsCfg.$System7G.$vFiler.$Vol7G.$Share.Comment
= $Comment
[Int]$CifsCfg.$System7G.$vFiler.$Vol7G.$Share.AccessRules
= 0
Columnize "ADD" 8 Cyan ($Share) 25
Yellow (" " + $Vol7G) 25 Yellow (" " + $PathAfterVolName)
40 Yellow
}
FUNCTION
Process-CifsShareAccessLine {
## MANIPULATION: Manipulation of $line ##
$Share = ($line.split('"'))[1]
$ToEndOfShare = 11 + 2 + ($share.length) + 2
$line =
$line.Substring($ToEndOfShare,($line.length - $ToEndOfShare))
$userGroupSID = ($line.Split("
"))[0]
$permission =
$line.Substring(($userGroupSID.length + 1),($line.length - $userGroupSID.length
- 1))
## CONSTRUCTION: Construction of $CifsCfg.$System7G.$vFiler ##
$Vol7G =
$CifsCfg.$System7G.$vFiler.ShareToVolume.$Share
$CifsCfg.$System7G.$vFiler.$Vol7G.$Share.AccessRules
++
$AccessRule =
$CifsCfg.$System7G.$vFiler.$Vol7G.$Share.AccessRules
[System.Object]$CifsCfg.$System7G.$vFiler.$Vol7G.$Share.$AccessRule
= @{}
$CifsCfg.$System7G.$vFiler.$Vol7G.$Share.$AccessRule.UserOrGroup
= $userGroupSID
$CifsCfg.$System7G.$vFiler.$Vol7G.$Share.$AccessRule.Permission
= $permission
Columnize "ACCESS" 8 Cyan $Share 25
Yellow (" " + $userGroupSID) 25 Yellow (" " + $permission)
40 Yellow
}
## CIFS: COLLECT AND PROCESS
cifsconfig_share.cfg FILES ##
##
==================================================== ##
Wr;Wr ">>>
COLLECT AND PROCESS cifsconfig_share.cfg FILES <<<" GREEN;Wr;Wr
Foreach($System7G in $Systems7G){
[System.Object]$CifsCfg.$System7G = @{}
Foreach($vFiler in
($vFilerList.$System7G.vFilers)){
Wr "Collecting the cifsconfig_share.cfg
file from vFiler $vFiler on $System7G :" GREEN;Wr
[System.Array]$CifsConfigFile = @()
$CifsConfigFile = GetConfigFile
"cifsconfig_share.cfg" $System7G $vFiler;Wr
Columnize "ADD" 8 Green "SHARE NAME" 25 Green
" VOLUME (7-MODE)" 25 Green " PATH" 40 Green
Columnize "ACCESS" 8 Green
"SHARE NAME" 25 Green " SID" 25 Green " PERMISSION"
40 Green
[System.Object]$CifsCfg.$System7G.$vFiler =
@{}
[System.Array]$CifsCfg.$System7G.$vFiler.Volumes = @()
[System.Object]$CifsCfg.$System7G.$vFiler.ShareToVolume
= @{}
Foreach($line in (ProcessArray
$CifsConfigFile -AllowHash)){
If($line.substring(0,16) -eq "cifs
shares -add"){
[Void](Process-CifsShareAddLine)
}elseif($line.substring(0,11) -eq "cifs
access"){
[Void](Process-CifsShareAccessLine)
}
};Wr
}
}
########################################
## PART 2: GENERATING
COMMANDS OUTPUT ##
########################################
Wr;Wr
">>>>>>> PART 2: GENERATING COMMANDS OUTPUT
<<<<<<<" MAGENTA;Wr
Wr;Wr "Clustershell
Commands Output Filename = " CYAN; Wr $OutputFileName;Wr
Wr;Wr
".................. PLEASE WAIT ..................." GREEN;Wr;Wr
FUNCTION Cshell{ ("#
" + $ClusterName + "::>"),("")}
[Int]$Spacing = 15
## CIFS: SHARE CREATE
COMMANDS FOR NEW VOLUME$ SHARES ##
## ==================================================
##
[System.Object]$CdotShareCount
= @{}
$CdotVolsArray |
Foreach{$CdotShareCount.$_ = 0}
$CdotVolsArray |
Foreach{$CdotShareCount.$_ ++}
FUNCTION
OUTPUT-CifsShareCreateVolumes {
Param([String]$ClusterName,[String]$SVMname)
Uline ("## CIFS: SHARE CREATE COMMANDS
FOR NEW VOLUME$ SHARES ##")
("# (1) Create VOLUME$ shares with
default properties")
("# (2) Removes the default Everyone
access")
("# (3) Adds BUILTIN\Administrators with
Full_Control")
("# (4) Adds NT AUTHORITY\Authenticated
Users with Change");("")
Cshell;$CdotVolsArray | Foreach{
[String]$VolPath = "/"
If($SlashVol){
$VolPath += "vol/"
}
$VolPath += $_
("vserver cifs share create -vserver
$SVMname -share-name $_$ -path $VolPath -share-properties $ShareProperties
-symlink-properties $SymlinkProperties -offline-files $OfflineFiles
-vscan-fileop-profile $VscanFileopProfile")
};("")
Cshell;$CdotVolsArray | Foreach{
("vserver cifs share access-control create
-vserver $SVMname -share $_$ -user-or-group BUILTIN\Administrators -permission
Full_Control")
};("")
Cshell;$CdotVolsArray | Foreach{
("vserver cifs share access-control
create -vserver $SVMname -share $_$ -user-or-group " + '"' + "NT
AUTHORITY\Authenticated Users" + '"' + " -permission
Change")
};("")
Cshell;$CdotVolsArray | Foreach{
("vserver cifs share access-control
delete -vserver $SVMname -share $_$ -user-or-group Everyone")
};("")
}
## CIFS: SHARE CREATE AND
ACCESS COMMANDS ##
##
====================================== ##
[Int]$ACLsCount = 0
[System.Object]$ShareConflictsText
= @{}
[System.Object]$ShareCreatesText
= @{}
[System.Object]$ShareAccessText
= @{}
$Systems7G | Foreach {
[System.Object]$ShareConflictsText.$_ = @{}
[System.Object]$ShareCreatesText.$_ = @{}
[System.Object]$ShareAccessText.$_ = @{}
[System.Array]$SpecialShares =
"ETC$","HOME","C$"
Foreach($Vol7G in ($CutoverVols.$_.VOLs7)){
$SpecialShares += ($Vol7G + "$")
}
Foreach($vFiler in ($vFilerList.$_.vFilers)){
[System.Array]$ShareConflictsText.$_.$vFiler
= @()
[System.Array]$ShareCreatesText.$_.$vFiler =
@()
[System.Array]$ShareAccessText.$_.$vFiler =
@()
$SpaceCreates = $SpaceAccess = 0
Foreach($Vol in
($CifsCfg.$_.$vFiler.Volumes)){
If($CutoverVols.$_.VOLs7 -contains $Vol){
Foreach($Share in
($CifsCfg.$_.$vFiler.$Vol.Shares)){
[String]$CifsCfg.$_.$vFiler.$Vol.$Share.CdotShareName = $Share
If(!($SpecialShares -Contains $share)){
[String]$newShare = $share
[Boolean]$dollarShare = $false
If($AppendFilerNameToShare){
If($newShare.substring(($newShare.length
-1),1) -eq "$"){
$dollarShare = $true
$newShare =
$newShare.Substring(0,($newShare.length -1))
}
If($vFiler -eq "vFiler0"){
$newShare = $newShare + "_" +
$_
}else{
$newShare = $newShare + "_" +
$vFiler
}
If($dollarShare){
$newShare = $newShare + "$"
}
[String]$CifsCfg.$_.$vFiler.$Vol.$Share.CdotShareName
= $newShare
}
If($CifsSharesSVM -Contains $newShare){
[Boolean]$valid = $false
[Boolean]$dollarShare = $false
[Int]$append = 2
while (!$valid){
If($newShare.substring(($newShare.length
-1),1) -eq "$"){
$dollarShare = $TRUE
}
[String]$tempShare = $newShare
If($dollarShare){
$tempShare =
$newShare.substring(0,($newShare.length-1))
}
$tempShare = $tempShare + "_"
+ [String]$append
If($dollarShare){
$tempShare += "$"
}
If(!($CifsSharesSVM -Contains
$tempShare)){
$valid = $true; $newShare = $tempShare
}
else{
$append++
}
}
$ShareConflictsText.$_.$vFiler +=
("# ++ WARNING ++ Share $share (from $_ vfiler $vFiler) already exists, we
will rename to: $newShare ")
$CifsSharesSVM += $newShare
$CifsCfg.$_.$vFiler.$Vol.$Share.CdotShareName = $newShare
}else{
$CifsSharesSVM += $share
}
## SECTION: CIFS SHARE CREATES ##
$ShareName =
$CifsCfg.$_.$vFiler.$Vol.$Share.CdotShareName
[String]$newPath = "/"
If($SlashVol){
$newPath += "vol/"
}
$newPath += ($MapVols.$_.$Vol +
$CifsCfg.$_.$vFiler.$Vol.$Share.PathAfterVolume)
$Comment =
$CifsCfg.$_.$vFiler.$Vol.$Share.Comment
If($Comment -ne ""){
$comment = " -comment " +
'"' + $comment + '"'
}
$ShareCreatesText.$_.$vFiler +=
("vserver cifs share create -vserver_PLACEHOLDER -share-name " +
'"' + $ShareName + '"' + " -path " + '"' + $newPath +
'"' + $comment + " -share-properties $ShareProperties
-symlink-properties $SymlinkProperties -offline-files $OfflineFiles -vscan-fileop-profile
$VscanFileopProfile")
$CdotShareCount.($MapVols.$_.$Vol) ++
$SpaceCreates ++
If($SpaceCreates -eq ($Spacing -1)){
$SpaceCreates = 0
$ShareCreatesText.$_.$vFiler +=
""
}
## SECTION: ACCESS RULES ##
[Boolean]$EveryoneFull = $false
$ARULES =
$CifsCfg.$_.$vFiler.$Vol.$Share.AccessRules
[Int]$ARULE = 1
while($ARULE -le $ARULES){
$UserGroupSID =
$CifsCfg.$_.$vFiler.$Vol.$Share.$ARULE.UserOrGroup
$Permission =
$CifsCfg.$_.$vFiler.$Vol.$Share.$ARULE.Permission
# Convert $UserGroupSID from SID (if it
is), to User/Group
If($UserGroupSID -eq
"everyone"){
$userGroupSID = "everyone"
}elseif($userGroupSID -eq
"S-NONE"){
$userGroupSID = "everyone"
}elseif(!$OnDomain){
Foreach ($linePair in $SIDtoNameMap){
$linePairSplit =
$linePair.split(",")
If($linePairSplit.count -eq 2){
If($userGroupSID -eq
$linePairSplit[0]){
$userGroupSID = $linePairSplit[1]
}
}
}
}else{
$objSID = New-Object
System.Security.Principal.SecurityIdentifier($userGroupSID)
$objUser =
$objSID.Translate([System.Security.Principal.NTAccount])
If($objUser){
$Global:SIDMapFileContent +=
$userGroupSID + "," + $objUser.Value
}else{
$Global:SIDMapFileContent +=
$userGroupSID + ",UNABLE_TO_TRANSLATE_SID"
}
# NB1: It doesn't matter if there are
duplicates in the list.
# NB2: $Global:SIDMapFileContent must
come before the below lines.
If($objUser){
$userGroupSID = $objUser.Value
}else{
Wr ("# ++ WARNING ++ UNABLE TO
TRANSLATE SID: $userGroupSID") RED;Wr
}
}
# Convert 7MODE Permission to CDOT
Permission
If($permission -eq "No
Access"){
$permission = "No_access"
}elseif($permission -eq '"emptydacl"'){
$permission = "No_access"
}elseif($permission -eq "Full
Control"){
$permission = "Full_control"
}elseif($permission -eq
'"nosd"'){
$permission = "Full_control"
}
If(($UserGroupSID -eq "everyone")
-and ($Permission -eq "Full_control")){
$EveryoneFull = $True
}
If(!$EveryoneFull){
If($UserGroupSID -ne
"everyone"){
$ShareAccessText.$_.$vFiler +=
("vserver cifs share access-control create -vserver_PLACEHOLDER -share
" + '"' + $ShareName + '"' + " -user-or-group " +
'"' + $userGroupSID + '"' + " -permission $permission")
}else{
$ShareAccessText.$_.$vFiler +=
("vserver cifs share access-control modify -vserver_PLACEHOLDER -share
" + '"' + $ShareName + '"' + " -user-or-group " +
'"' + $userGroupSID + '"' + " -permission $permission")
$EveryoneFull = $True
}
$SpaceAccess ++
If($SpaceAccess -eq ($Spacing -1)){
$SpaceAccess = 0
$ShareAccessText.$_.$vFiler +=
""
}
$ACLsCount ++
}
$ARULE++
}
If(!$EveryoneFull){
$ShareAccessText.$_.$vFiler +=
("vserver cifs share access-control delete -vserver_PLACEHOLDER -share
" + '"' + $ShareName + '"' + " -user-or-group
Everyone")
$SpaceAccess ++
If($SpaceAccess -eq ($Spacing -1)){
$SpaceAccess = 0
$ShareAccessText.$_.$vFiler +=
""
}
}else{
$ACLsCount++
}
}
}
}
}
}
}
FUNCTION
OUTPUT-CifsShareCreate{
Param([String]$ClusterName,[String]$SVMname)
Uline ("## CIFS: SHARE CREATE AND ACCESS
COMMANDS ##")
("# NB1: We ignore the 7-Mode default
shares ETC$,HOME,C$ and OLDVOLUMENAME$ shares")
("# NB2: A CIFS share create
automatically gives Everyone Full_control, we do not recreate this!")
("# Before starting please run the
below:");("")
Cshell; ("rows 0")
("cifs share access-control show -fields
share -vserver $SVMname")
("# RECORD THE NUMBER OF ACLS ABOVE FOR
LATER USE!");("")
Foreach($7Gsystem in $Systems7G){
Foreach($vFiler in
$vFilerList.$7Gsystem.vFilers){
("## FOR $7Gsystem AND VFILER $vFiler
##");("")
($ShareConflictsText.$7Gsystem.$vFiler);("")
Cshell
Foreach($line in
$ShareCreatesText.$7Gsystem.$vFiler){
$line.replace("-vserver_PLACEHOLDER","-vserver
$SVMname")
};("")
Cshell
Foreach($line in $ShareAccessText.$7Gsystem.$vFiler){
$line.replace("-vserver_PLACEHOLDER","-vserver
$SVMname")
};("")
}
}
("# TO VERIFY THE CORRECT NUMBER OF
SHARES HAVE BEEN CREATED:");("")
Cshell
Foreach ($Vol in $CdotVolsArray){
$ShareCount = $CdotShareCount.$Vol
("cifs share show -path *$Vol* -fields
share-name -vserver $SVMname")
("# EXPECTED SHARES =
$ShareCount");("")
};("")
("# TO VERIFY THE CORRECT NUMBER OF ACLS
EXIST:");("")
Cshell
("cifs share access-control show -fields
share -vserver $SVMname")
("# EXPECTED ADDITIONAL ACLS = $ACLsCount
");("")
}
####################
## PART 3: OUTPUT ##
####################
[System.Array]$Output = @()
$Output += Uline ("##
CS7C: COMMANDS GENERATED " + (Get-Date -uformat %d%h%G) + " ##")
$Output += ("# CAVEAT
UTILITOR! This tool comes with no support and no warranty, please REVIEW and
SANITY CHECK!")
$Output += ("# '++
WARNING ++' indicates detected conflicts - search the output for these and
review.")
$Output += ("# NB:
Transition commands should be generated from the LATEST 7-Mode and CDOT
information!"),("")
$Output += Uline ("##
>>>>> COMMANDS TO APPLY CIFS SHARES <<<<<
##")
$Output +=
OUTPUT-CifsShareCreateVolumes $Cluster $SVM
$Output +=
OUTPUT-CifsShareCreate $Cluster $SVM
$Output | Set-Content
$OutputFileName
Notepad $OutputFileName
If($OnDomain){
$Global:SIDMapFileContent | Set-Content
$SIDtoNameMapFilePath
}
Press-Enter
Comments
Post a Comment