Posts mit dem Label Powershell werden angezeigt. Alle Posts anzeigen
Posts mit dem Label Powershell werden angezeigt. Alle Posts anzeigen

Dienstag, 7. September 2021

Loseless Merging Directories with Powershell

 

I needed a nice little function for merging directories without loosing documents in case of collisions of paths. Because i needed this for tidying up a hell of messed up homedrives i didnt care about any ACL etc.

function MoveCollisionFree([string]$srcdir,[string]$dstdir){
$srcdir = $srcdir.TrimEnd('\')
$dstdir = $dstdir.TrimEnd('\')
$srcRegEx=[regex]::Escape($srcdir)

[System.IO.Directory]::GetDirectories($srcdir).ForEach({
$DestPath=$_ -replace($srcRegEx,$dstdir)
if([System.IO.Directory]::Exists($DestPath)){
MoveCollisionFree -srcdir $_ -dstdir $DestPath
}else{[System.IO.Directory]::Move($_,$DestPath)}
})
[System.IO.DirectoryInfo]::new($srcdir).GetFiles().ForEach({
$DestFile=[System.IO.FileInfo]::new($($_.FullName -replace($srcRegEx,$dstdir)))
if($DestFile.Exists){
if($DestFile.LastWriteTime -ge $_.LastWriteTime){
$_.MoveTo("$($DestFile.Directory.FullName)\$($_.BaseName)_older_from_$($_.LastWriteTime.ToString('yyyy-MM-dd'))$($_.Extension)")
}else{
$NewFileName=$DestFile.FullName
$DestFile.MoveTo("$($DestFile.Directory.FullName)\$($_.BaseName)_older_from_$($DestFile.LastWriteTime.ToString('yyyy-MM-dd'))$($_.Extension)")
$_.MoveTo($NewFileName)
}
}else{$_.MoveTo($DestFile.FullName)}
})
Remove-Item $srcdir -Recurse -Force -Confirm:$false
}

Freitag, 1. November 2019

Add a Netapp LUN as VM Datastore per Powershell

You can speak Powershell to Netapp and VMware, so adding a LUN as Datastore should not a problem, despite the fact that Netapp Powershell command get-nclun does not deliver the worldwidename of the lun per default.

But according this KB from Netapp a LUN NAA is just a prefix + serial ascii to hex converted.

https://kb.netapp.com/app/answers/answer_view/a_id/1033595/~/how-to-match-a-luns-naa-number-to-its-serial-number-

This is "stupid" adding all LUNs as Datastore using the filename of the LUN as Suffix.

Get-NcLun|select Node,Vserver,Path,
 @{N='NAA';E={"naa.600a0980$(-join ($_.SerialNumber.ToCharArray()|%{'{0:x}' -f $([byte][char]$_)}))"}}|%{
  get-vmhost esxserver|New-Datastore -Vmfs -Name "VMFS_$($_.Path.Split('/')[2])" -Path $_.NAA
  }

Maybe better declaring a function to make Code better readable ...

function Convert-ASCIItoHEX_STRING ([string]$inputstring){
return $(-join ($inputstring.ToCharArray()|%{'{0:x}' -f $([byte][char]$_)}))
}

Get-NcLun|select Node,Vserver,Path,
 @{N='NAA';E={"naa.600a0980$(Convert-ASCIItoHEX_STRING $_.SerialNumber)"}}|%{
  get-vmhost esxserver|New-Datastore -Vmfs -Name "VMFS_$($_.Path.Split('/')[2])" -Path $_.NAA
  }

I hope this comes handy sometimes ..

Mittwoch, 7. Februar 2018

Get Fibrechannel WWPNs and alot other HW Info from Fujitsu iRMC4 per Powershell

Pssst .. wanna get ALL the cool hardware info you see on an iRMC4 WebGui in a Powershell object ?
If you need even the fibrechannel stuff, you won't get it by REST,CIM or WSMAN - i deep-dived some days into all kind of documentations, wasted alot of time in enumerating and finally gave up, the only way seems to be get it from the WebGui - shame on Fujitsu - DELL do it better, see my next post.

This quick-n-dirty shit worked fine for me for PRIMERGY RX2540 M1, PRIMERGY RX2540 M2, PRIMERGY RX4770 M2 and PRIMERGY RX300 S8 - nice for report all MAC, WWPNs, Serials, Firmware etc ... if you use it let me know.

function Get-iRMC_HWInfo($irmcname,$irmcuser,$irmcpw)
{
    $rsacred=New-Object System.Management.Automation.PsCredential($irmcuser,$(ConvertTo-SecureString -String $irmcpw -AsPlainText -force)) 
    $body = @{APPLY = 99;P99='Login'}
    $irmcwebreq=Invoke-WebRequest "http://$irmcname/login" -SessionVariable irmcsession -Credential $rsacred -Method Post -Body $body
    $hwinfo=$($irmcwebreq.AllElements|?{$_.TagName -eq 'TR'}|?{$_.innerText -match '^System Type|^Serial|^System GUID|^System Name|^System\ O/S'}).innerText    
    $networkinventorylink=$($irmcwebreq.Links|?{$_.innerHTML -eq 'Network Inventory'}).href
    $irmcwebreq2=Invoke-WebRequest "http://$irmcname/$networkinventorylink" -WebSession $irmcsession 
    $tabellen=$irmcwebreq2.ParsedHtml.getElementsByTagName("TABLE")
    $nictabelle=$tabellen|?{$_.summary -match 'Ethernet'}
    $fctabelle=$tabellen|?{$_.summary -match 'Fibre'}
    $nicports=@()
    foreach($datarow in $nictabelle.rows){
        if($datarow.cells[0].tagName -eq "TD"){
            $nicports+=@{Enabled=$datarow.cells[0].innerHTML -match 'ok.gif';
                SlotID=$datarow.cells[1].innerText;
                FunctionID=$datarow.cells[2].innerText;
                PortID=$datarow.cells[3].innerText;
                Firmware=$datarow.cells[5].innerText;
                OpROM=$datarow.cells[6].innerText;
                Interface=$datarow.cells[7].innerText;
                VenID=$datarow.cells[9].innerText;
                DevID=$datarow.cells[10].innerText;
                SubVenID=$datarow.cells[11].innerText;
                SubDevID=$datarow.cells[12].innerText;
                MAC=$datarow.cells[14].innerText
            }
        }
    }

    $fcports=@()
    foreach($datarow in $fctabelle.rows){
        if($datarow.cells[0].tagName -eq "TD"){
            $fcports+=@{Enabled=$datarow.cells[0].innerHTML -match 'ok.gif';
                SlotID=$datarow.cells[1].innerText;
                FunctionID=$datarow.cells[2].innerText;
                PortID=$datarow.cells[3].innerText;
                Firmware=$datarow.cells[5].innerText;
                OpROM=$datarow.cells[6].innerText;
                Interface=$datarow.cells[7].innerText;
                VenID=$datarow.cells[9].innerText;
                DevID=$datarow.cells[10].innerText;
                SubVenID=$datarow.cells[11].innerText;
                SubDevID=$datarow.cells[12].innerText;
                WWNN=$datarow.cells[14].innerText;
                WWPN=$datarow.cells[15].innerText}
            }
        }
    return [pscustomobject]@{
        SysType=$hwinfo[0].Split(':')[1];
        SysSerial=$hwinfo[1].Split(':')[1];
        SysGUID=$hwinfo[2].Split(':')[1];
        SysName=$hwinfo[3].Split(':')[1];
        SysOS=$hwinfo[4].Split(':')[1];
        nicports=$nicports;
        fcports=$fcports
 }

}

Yeah thats all folks - ugly quick-n-dirty.

Mittwoch, 1. Juni 2016

Powershell reporting and fixing up IPv4 Subnet masks in a Windows Enviroment

Here have some Powershell for fixing up a "wrong" static set Subnetmask, like you have after resizing a Subnet - or got the wrong mask reported from the network guys.

So you heard about some wrong set up Subnets, uups this can happen. So first i would like to report all my windows servers in my ActiveDirectory and their setup Subnet mask on the IP address which is in DNS. Observing the report before fixing maybe nice, thatswhy DO NOT just copy&paste this code in one Script and run, maybe put it in ISE and run just selected code.

#How to Report 

Import-Module ActiveDirectory

$reportfilename = c:\Report-SRVs_SubNets.csv

Function Get-DnsEntry($iphost)
{
 If($ipHost -match "^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$")
  {
    [System.Net.Dns]::GetHostEntry($iphost).HostName
  }
 ElseIf( $ipHost )#-match "^.*\.\.*")
   {
    [System.Net.Dns]::GetHostEntry($iphost).AddressList[0].IPAddressToString
   } 
 ELSE { Throw "Specify either an IP V4 address or a hostname" }
}


$Servers = Get-ADComputer -Server $DCSRV -Filter {OperatingSystem -Like "*Server*"} -Properties *

$OutputReport = @()
[int64]$IntCounter=0
foreach ($Server in $Servers){
    $IntCounter+=1
    Write-Host $Server.Name " :  $IntCounter von " $Servers.Count
    $MYSRVInfo = '' |Select DNSHostname,DHCP,IPAddress,IPSubnet,Pingable,PWAge,OperatingSystemVersion,
    $MYSRVInfo.DNSHostname = $Server.DNSHostName
    if ($Server.DNSHostName) {$MYSRVInfo.IPAddress = Get-DnsEntry($Server.DNSHostName)}
    $MYSRVInfo.PWAge = $(New-TimeSpan -Start $([datetime]::FromFileTime($Server.pwdLastSet)) -End (get-date)).Days
    $MYSRVInfo.OperatingSystemVersion = $Server.OperatingSystemVersion
    $MYSRVInfo.Service_Pack = $Server.OperatingSystemServicePack
    try {
$IPCFG=Get-WmiObject -ComputerName $MYSRVInfo.IPAddress Win32_NetworkAdapterConfiguration -Properties IPAddress,IPSubnet,DHCPEnabled -ErrorAction Stop|?{$_.IPAddress -match $MYSRVInfo.IPAddress}
$MYSRVInfo.IPSubnet=$IPCFG.IPSubnet[$IPCFG.IPAddress.IndexOf($MYSRVInfo.IPAddress)]
$MYSRVInfo.DHCP=$IPCFG.DHCPEnabled
} catch {
$MYSRVInfo.IPSubnet='NOWMI'
$MYSRVInfo.DHCP='NOWMI'
}
    $MYSRVInfo.IPSubnet = 
    $OutputReport +=$MYSRVInfo
    if ($IntCounter % 20 -eq 0) {
        $OutputReport|Export-Csv -NoTypeInformation -Delimiter ';' -Path $reportfilename
        }
}

$OutputReport|Export-Csv -NoTypeInformation -Delimiter ';' -Path $reportfilename

# How To Fix now a certain Subnet from the Report

$ipscopetofixregex='10.1.2.*'
$rightsubnet='255.255.254.0'

# Filter now your Report 

$srvkaputt=Import-Csv -Delimiter ';' $reportfilename|?{($.IPAddress -match $ipscopetofixregex) -and ($_.IPSubnet -ne $rightsubnet) -and ([int]$_.DHCP -ne 1) -and ($_.DHCP -ne 'NOWMI')}

# Use WMI to fix it up - but be aware this code kills fixed IPv6 addresses and interrupt network traffic "slightly"

$srvkaputt|%{
    $ip=$_.IPAddress
    start-job -Args $_.IPAddress,$rightsubnet -scriptblock {
        param($ip,$sub)
        $IPCFG=(Get-WmiObject -ComputerName $ip Win32_NetworkAdapterConfiguration|?{$_.IPAddress -match $ip})
        $IPSUBNET=[string[]]($IPCFG.IPSubnet.Clone()|?{$_ -match "^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$"})
        $IPADDRES=[string[]]($IPCFG.IPAddress.Clone()|?{$_ -match "^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$"})
        $IPSUBNET[$IPADDRES.IndexOf($ip)]='$sub'
        $IPCFG.EnableStatic($IPADDRES,$IPSUBNET)
        }
    }

# Check with Get-Job maybe hunged jobs after a while and Kill them Get-Job|Remove-Job -f 

Montag, 2. Mai 2016

Delete huge folder structures where 260 character limit will stops you


Get annoyed by this fricking stupid path length limit of 260 characters when you just want a huge Folder send down the digital Jordan.
I needed this script to kill a folder structure on a Netapp FAS over CIFS with alot of personal folders (old profiles) with alot messed up ACLs. Be sure that you run it with a user which is in Administrator group.

https://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath

This PS script walk recursivly through huge folder structures and rename them beginning from top to down 0-9999 before delete them in reverse order.

function Kill-FilePathLimit ([string]$fatpath)
{
    $list=Get-ChildItem -Directory $fatpath
    if ($list) {
        0..$($list.count - 1)|%{
            try{
                Rename-Item $list[$_].FullName $("{0:D4}" -f $_) -ErrorAction Stop
            } catch {
                $AccessRule = new-object System.Security.AccessControl.FileSystemAccessRule $([System.Security.Principal.WindowsIdentity]::GetCurrent().Name,"FullControl","Allow")
                $ICH = New-Object System.Security.Principal.NTAccount([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)
                $ACL=Get-Acl $list[$_].FullName
                $acl.SetOwner($ICH)
                Set-Acl $list[$_].FullName -AclObject $acl
                $acl.SetAccessRule($AccessRule)
                Set-Acl $list[$_].FullName
                Rename-Item $list[$_].FullName $("{0:D4}" -f $_) -ErrorAction Stop
            }
        }
        Get-ChildItem -Directory $fatpath|%{
            Kill-FilePathLimit $_.FullName
        }
    } else {
        Remove-Item -Recurse $fatpath -Force -Confirm:$false
    }
}