Step 1: Install RacADM

$computerlist=@'
SERVER1
SERVER2
'@
$computernames=@($computerlist -split "`n")|%{$_.Trim()}
$fileURL="https://dl.dell.com/FOLDER08543783M/1/DellEMC-iDRACTools-Web-WINX64-10.3.0.0-4945.exe"
$expectedExecutable='racadm.exe'
$expectedInstallPath='C:\Program Files\Dell\SysMgt\iDRACTools\racadm'
$stageFolder='C:\Temp\'


function installProgramFromExeZipArchive{
    param(
        $computernames=$env:computername,
        $fileURL="https://dl.dell.com/FOLDER07549599M/1/DellEMC-iDRACTools-Web-WINX64-10.2.0.0-4583_A00.exe",
        $expectedExecutable='racadm.exe',
        $expectedInstallPath='C:\program files\Dell\SysMgt\iDRACTools\racadm',
        $stageFolder='C:\Temp\'
    )
    $results=[hashtable]@{}
    function addEnvironmentalPath($pathToAdd){
        $registryEnvironment='Registry::HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment'
        $pathToAdd=if($pathToAdd -match '\\$'){$pathToAdd -replace '.$'}else{$pathToAdd}
        try{
            $originalPaths=(Get-ItemProperty -Path $registryEnvironment -Name PATH).path
            $pathsArray=$originalPaths -split ';'|?{$_.trim() -ne ''}|%{if($_ -match '\\$'){$_ -replace '.$'}else{$_}}|Sort-Object -Unique
            # dotNet method: [Environment]::SetEnvironmentVariable('Foo', 'Bar', 'Machine')
            # legacy method: setx /M PATH "%PATH%;C:\Something\bin"
            if($pathToAdd -in $pathsArray){
                write-host "$pathToAdd is already included in the environmental paths: '$originalPaths'"
                return $true
            }else{
                $newPathsArray=$pathsArray+$pathToAdd
                $newPaths=$newPathsArray -join ';'
                Set-ItemProperty -Path $registryEnvironment -Name PATH -Value $newPaths
                $newRegistryEnvironment=(Get-ItemProperty -Path $registryEnvironment -Name PATH).Path
                write-host "Environmental paths have been changed:`r`nFrom: $originalPaths`r`nTo: $newPaths"
                return $true
            }
            # non-persistent environmental reload
            # $Env:Path=[System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")  
        }catch{
            write-warning $_
            return $false
        }
    }
    foreach($computerName in $computernames){
        $alreadyInstalled=invoke-command -computername $computername -scriptblock{
            param($expectedExecutable,$addEnvironmentalPath,$expectedInstallPath)            
            $validCommand=try{
                get-command $expectedExecutable -EA Ignore
            }catch{
                $false
            }
            if($validCommand){
                return $validCommand
            }else{
                if(test-path "$expectedInstallPath\$expectedExecutable" -EA Ignore){
                    [scriptblock]::create($addEnvironmentalPath).invoke($expectedInstallPath)
                    $env:Path=[System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
                    return $(get-command $expectedExecutable -EA Ignore)
                }else{
                    return $false
                }
            }
        } -Args $expectedExecutable,${function:addEnvironmentalPath},$expectedInstallPath
        if($alreadyInstalled){
            write-host "$computername has already installed $expectedExecutable"
            $results+=[hashtable]@{$computername=$true}
        }else{
            # Autogen variables
            $fileName=[regex]::match($fileURL,'[^/\\&\?]+\.\w{3,4}(?=([\?&].*$|$))').value
            $translatedVolume=[regex]::match($stageFolder,'^(\w)\:').captures.groups[1].value+'$'
            $translatedFoldername=[regex]::match($stageFolder,'\:(.*)$').captures.groups[1].value
            $remoteSmbPath=join-path $('\\'+$computerName+"\$translatedVolume") $translatedFoldername            
            try{
                # Download the file directly onto target server's staging folder
                Import-Module BitsTransfer
                if(!(test-path $remoteSmbPath)){$null=mkdir $remoteSmbPath}
                # Start-BitsTransfer -Source $fileURL -Destination $output
                [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
                Start-BitsTransfer -Source $fileURL -Destination $remoteSmbPath
                $psSession=new-pssession $computerName
                if($psSession.State -eq 'Opened'){
                    write-host "Now attempting to install $expectedExecutable on $computername..."
                    $result=invoke-command -Session $psSession -ScriptBlock{
                        param($stageFolder,$filename,$expectedExecutable,$expectedInstallPath,$addEnvironmentalPath)
                        # write-host "$env:computername : $stageFolder,$filename,$expectedExecutable,$expectedInstallPath"
                        # pause                 
                        $commandAvailable=try{get-command $expectedExecutable -EA Ignore}catch{$false}
                        if(!$commandAvailable -and $(test-path "$expectedInstallPath\$expectedExecutable" -EA Ignore)){
                            # if(!($env:path -like "*$expectedInstallPath*")){$env:path+=";$expectedInstallPath"}                     
                            # $null=RefreshEnv                            
                            $null=[scriptblock]::create($addEnvironmentalPath).invoke($expectedInstallPath)
                            $env:Path=[System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
                            $commandAvailable=try{get-command $expectedExecutable -EA Ignore}catch{$false}
                        }
                        if (!$commandAvailable){
                            write-host "Installing $expectedExecutable on $env:computername ..."
                            # $exeExists=try{ls $expectedInstallPath -EA Ignore|?{$_.Name -like $expectedExecutable}}catch{$false}
                            if($(test-path "$expectedInstallPath\$expectedExecutable" -EA Ignore)){
                                $null=[scriptblock]::create($addEnvironmentalPath).invoke($expectedInstallPath)
                                $env:Path=[System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
                                # $null=RefreshEnv
                                $commandNowAvailable=try{get-command $expectedExecutable -EA Ignore}catch{$false}
                                if($commandNowAvailable){
                                    return $true
                                }else{
                                    return $false
                                    }
                            }else{
                                $expectedFileLocation=join-path $stageFolder $filename
                                $zipFilename=$([System.IO.Path]::GetFileNameWithoutExtension($expectedFileLocation))+'.zip'
                                $newZipFile=join-path $stageFolder $zipFilename
                                #[System.IO.Path]::GetExtension($expectedFileLocation)
                                Rename-Item -Path $expectedFileLocation -NewName $newZipFile -EA Ignore
                                # $null=Expand-Archive -Path $newZipFile -DestinationPath $stageFolder
                                # alternative method: backward compatible to older systems
                                Add-Type -AssemblyName System.IO.Compression.FileSystem
                                $null=[System.IO.Compression.ZipFile]::ExtractToDirectory($newZipFile, $stageFolder)
                                $msiFile=(ls $stageFolder|?{$_.FullName -match '\.msi$'}|sort -property LastWriteTime|select -first 1).FullName
                                Start-Process $msiFile -ArgumentList "/quiet" -wait
                                # this command doesn't work: msiexec /i $msiFile /quiet /qn /norestart
                                # $environmentalPathExists=$env:path -like "*$expectedInstallPath*"
                                $commandAvailable=try{get-command $expectedExecutable -EA Ignore}catch{$false}
                                if(!$commandAvailable -and $(test-path $expectedInstallPath -EA Ignore)){
                                    $null=[scriptblock]::create($addEnvironmentalPath).invoke($expectedInstallPath)
                                    $env:Path=[System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
                                    #$env:path+=";C:\Program Files\Dell\SysMgt\iDRACTools\racadm"
                                    #$null=RefreshEnv
                                }
                                $commandNowAvailable=try{get-command $expectedExecutable -EA Ignore}catch{$false}
                                if($commandNowAvailable){return $true}else{return $false}
                            }
                        }else{
                            write-host "Command $expectedExecutable is available on $env:computername"
                            return $true
                        }                    
                    } -Args $stageFolder,$fileName,$expectedExecutable,$expectedInstallPath,${function:addEnvironmentalPath}
                    Remove-PSSession $psSession
                    write-host "$computername result: $result"
                    $results+=[hashtable]@{$computername=$result}
                }else{
                    write-warning "Unable to connect to $computername via WinRM"
                    $results+=[hashtable]@{$computername=$null}
                }
            }catch{
                write-warning $_
                $results+=[hashtable]@{$computername=$null}
            }
        }
        if($computername -like "$env:computername*"){
            $env:Path=[System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
        }
    }
    return $results
}
installProgramFromExeZipArchive $computernames $fileURL $expectedExecutable $expectedInstallPath $stageFolder

Step 2: Invoke-Command toward a list of Remote Computers

$computerlist=@'
SERVER1
SERVER2
'@
$computernames=@($computerList -split "`n")|%{$_.Trim()}
$adminUid=2
$preferredAdminUsername='sysadmin'
$preferredPassword='PASSWORD1'
$admin2Username='backupadmin'
$admin2Password='PASSWORD2'
$admin2Uid=3
$alertEmailAddress='[email protected]'

$results=@()
foreach ($computername in $computernames){
    $commands=@(
        'racadm set iDRAC.EmailAlert.Enable.1 0', # disable email alerts prior to running commands
        "racadm set system.lcd.LCDUserString $computername",
        "racadm set iDRAC.NIC.DNSRacName $computername",
        'racadm set iDRAC.Webserver.HostHeaderCheck 0', # Pre-empt SSL cert issues 
        'racadm set iDRAC.NIC.DNSRegister 0',
        'racadm set iDRAC.IPv4.DHCPEnable 1',
        'racadm set iDRAC.IPv4.DNSFromDHCP 1',
        'racadm set iDRAC.NIC.DNSDomainFromDHCP 1',    
        'racadm set iDRAC.NIC.VLanEnable 0',
        "racadm set iDRAC.Users.$adminUid.UserName $preferredAdminUsername",
        "racadm set iDRAC.Users.$adminUid.Password $preferredPassword", 
        "racadm set iDRAC.Users.$admin2Uid.UserName $admin2Username",
        "racadm set iDRAC.Users.$admin2Uid.Password $admin2Password",
        "racadm set iDRAC.Users.$admin2Uid.Enable 1",
        "racadm set iDRAC.Users.$admin2Uid.Privilege 0x1ff",  # hex code for admin privilege   
        "racadm set iDRAC.EmailAlert.Address.1 $alertEmailAddress",
        'racadm set iDRAC.EmailAlert.Enable.1 1'
    )

    # $commands=@(
    #     'racadm set iDRAC.EmailAlert.Enable.1 0', # disable email alerts prior to running commands
    #     'racadm set iDRAC.EmailAlert.Enable.1 1'
    # )

    # invokeRacAdmCommands $computername $command
    $computername=[regex]::match($computername,'([a-zA-Z0-9-]{1,15})\.{0,1}').captures.groups[1].value # sanitize: remove ltd suffexes
    $result=invoke-command -computername $computername {
        param($commands)
        write-host "Processing $env:computername..."
        if(!(get-command racadm -EA Ignore)){
            try{
                $Env:Path=[System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
                $null=get-command racadm                
            }catch{
                write-warning $_
                return "$env:computername commands overall: Failed (racadm.exe not available)"
            }
        }
        $successes=@()
        foreach($command in $commands){
            write-host $command -nonewline
            $success=invoke-expression $command
            $passed=if($success|Select-String 'successfully'){
                write-host ': success' -foregroundcolor Green
                'success'
            }else{
                write-host ': failed' -foregroundcolor Red
                'failed'
            }
            $successes+="$command`: $passed"
        }
        if('failed' -notin $successes){
            $comment="$env:computername commands overall: Passed"
            write-host $comment -foregroundcolor Green
        }else{            
            $comment="$env:computername commands overall: Failed"
            write-host $comment -foregroundcolor Red
            }
        $successes=,$comment+$successes
        return $($successes|out-string)
    } -Args (,$commands)
    $results+=$result
    # pause
}

Alternatively, use RacAdm API from a Central ‘Jump Host’

$iDracInterfaces=@'
server1.drac.kimconnect.com
server2.drac.kimconnect.com
'@

$iDracInterfaces=@($iDracInterfaces -split "`n")|%{$_.Trim()}
$possibleCredentials=@(
    @{username='sysadmin';password='PASSWORD'},
    @{username='root';password='calvin'}
)
$adminUid=2
$preferredAdminUsername='sysadmin'
$preferredPassword='PASSWORD'
$admin2Username='backupadmin'
$admin2Password='PASSWORD2'
$admin2Uid=3
$alertEmailAddress='[email protected]'
$commands=@(
    "set system.lcd.LCDUserString $env:computername",
    "set iDRAC.NIC.DNSRacName $env:computername",
    'set iDRAC.NIC.DNSRegister 0',
    'set iDRAC.IPv4.DHCPEnable 1',
    'set iDRAC.IPv4.DNSFromDHCP 1',
    'set iDRAC.NIC.DNSDomainFromDHCP 1',    
    'set iDRAC.NIC.VLanEnable 0',    
    "set iDRAC.Users.$admin2Uid.UserName $admin2Username",
    "set iDRAC.Users.$admin2Uid.Password $admin2Password",
    "set iDRAC.Users.$admin2Uid.Enable 1",
    "set iDRAC.Users.$admin2Uid.Privilege 0x1ff",  # code for admin privilege
    'set iDRAC.EmailAlert.Enable.1 1',
    "set iDRAC.EmailAlert.Address.1 $alertEmailAddress"
)

# make a comment to edge case where usernames collide
function remoteRacAdmCommands{
    param(
        $iDracInterfaces,
        $possibleCredentials,
        $commands,        
        $preferredAdminUsername='root',
        $preferredPassword='calvin',
        $adminUid=2
    )
    $ErrorActionPreference = 'stop'
    $results=[hashtable]@{}
    
    function invokeRacCommand($command){
        write-host $command -nonewline
        $success=invoke-expression $command
        if($success|Select-String 'successfully'){
            write-host ': success' -foregroundcolor Green
            return $true
        }else{
            write-host ': failed' -foregroundcolor Red
            return $false
        }
    }    
    foreach($computername in $iDracInterfaces){    
        $validIp=try{test-connection $computername -Count 1 -EA Ignore}catch{$false}
        if($validIp){
            $ipAddress=$validIp.IPV4Address.IPAddressToString
            $goodCredentials=.{            
                write-host "Attempting to connect to $computername via $ipAddress"
                foreach ($credentials in $possibleCredentials){
                    $testUsername=$credentials.username
                    $testPassword=$credentials.password
                    $test=racadm -r $ipAddress -u $testUsername -p $testPassword getractime
                    if($null -ne $test -and $test -match '\d{2}\:\d{2}\:\d{2}'){
                        write-host "Valid credentials on $ipAddress`: $testUsername/$testPassword"
                        return $credentials
                    }else{
                        write-warning "Test of username $testUsername with password $testPassword has failed."
                        $null=ping 127.0.0.1               
                    }
                }
                return $null
            }
            if($goodCredentials){
                $username=$goodCredentials.username
                $password=$goodCredentials.password
                $successes=@()
                foreach($command in $commands){
                    $remoteCommand="racadm -r $ipAddress -u $username -p $password $command"
                    $success=invokeRacCommand $remoteCommand
                    $successes+=$success                    
                }
                $result=if($null -eq $($successes|?{$_ -eq $false})){'Passed'}else{'Failed'}
            }else{
                write-warning "Unable to login due to incorrect passwords"
                $result='incorrect passwords'
            }
        }else{
            write-warning "$computername is NOT pingable. Hence it's being skipped"
            $result='NOT pingable'
        }
        $results+=[hashtable]@{$computername=$result}
    }
    return $results
}

remoteRacAdmCommands $iDracInterfaces $possibleCredentials $commands $preferredAdminUsername $preferredPassword $adminUid
OLD Notes…
Configure iDrac Settings
# Download and install RacAdm 10.2 :
$url='https://dl.dell.com/FOLDER07549599M/1/DellEMC-iDRACTools-Web-WINX64-10.2.0.0-4583_A00.exe'
$tempDir='C:\Temp'
mkdir $tempDir; cd $tempDir
wget $url
write-host "Please install RacAdm from $temp or search for a script with function named installProgramFromExeZipArchive to automate this process"
# Run this command after RacAdm is installed
$env:path += ";C:\Program Files\Dell\SysMgt\iDRACTools\racadm"; refreshenv
# Setup iDrac with standardized default settings
$adminUid=2
$adminPassword='insertPasswordHere'
racadm set iDRAC.Users.$adminUid.UserName admin
racadm set iDRAC.Users.$adminUid.Password $adminPassword
racadm set iDRAC.NIC.DNSRacName ($env:computername).tolower()
racadm set iDRAC.NIC.DNSRegister 0
racadm set iDRAC.IPv4.DHCPEnable 1
racadm set iDRAC.IPv4.DNSFromDHCP 1
racadm set iDRAC.NIC.DNSDomainFromDHCP 1
racadm set iDRAC.NIC.VLanEnable

How to execute racadm toward remote targets

# General syntax
racadm -r <racIpAddr> -u <username> -p <password> get <devicename>.<groupname>.[<index>].[<objectname>]
racadm -r <racIpAddr> -u <username> -p <password> set <devicename>.<groupname>.[<index>].<objectname> <value>
# Script example: how to set an alerting email address
$remoteNodes=@'
idracIP1
idracIP2
'@
$adminUsername='root'
$adminPassword='somepasswordhere'
$emailAddress='[email protected]'

$remoteNodes=@($remoteNodes -split "`n")|%{$_.Trim()}
foreach ($idracInterface in $remoteNodes){
    try{
        $commandsCount=2
        $command1="racadm -r $idracInterface -u $adminUsername -p `$adminPassword set iDRAC.EmailAlert.Enable.1 1"       
        $command2="racadm -r $idracInterface -u $adminUsername -p `$adminPassword set iDRAC.EmailAlert.Address.1 $emailAddress"
        write-host $command1
        $result=racadm -r $idracInterface -u $adminUsername -p $adminPassword set iDRAC.EmailAlert.Enable.1 1
        write-host $command2
        $result+=racadm -r $idracInterface -u $adminUsername -p $adminPassword set iDRAC.EmailAlert.Address.1 $emailAddress
        # racadm -r $idracInterface -u $adminUsername -p $adminPassword get iDRAC.EmailAlert.Enable.1
        # racadm -r $idracInterface -u $adminUsername -p $adminPassword get iDRAC.EmailAlert.Address.1
        $successes=($result|Select-String 'successfully').count
        if($successes -ge $commandsCount){
            write-host "$idracInterface commands successful: $successes" -foregroundcolor Green
        }else{
            write-warning "$idracInterface commands $successes of $commandsCount successful"
        }
    }catch{
        write-warning $_
    }
}