Increase Substring length dynamically - powershell

I am new to the community and need some help in Powershell.
I want the following code to dynamically check if the specific $sAMAccountName exists in an array or not.
If it exists, keep increasing the substring length by 1 and check the array again.
Instead of defining more variables like $sAMAccountName1 and $sAMaccountName2 (and so on) manualy.
$Nachname = "Nachname"
$Vorname = "Vorname"
$sAMAccountName = $Nachname+$Vorname.Substring(0,1)
$sAMAccountName1 = $Nachname+$Vorname.Substring(0,2)
$sAMAccountName2 = $Nachname+$Vorname.Substring(0,3)
$Array = #('NachnameV','NachnameVo','NachnameVor')
if($sAMAccountName -notin $Array){
Write-Host "$sAMAccountname does not exist :-)"
}
elseif($sAMAccountName1 -notin $Array){
Write-Host "$sAMAccountName1 does not exist :-)"
}
elseif($sAMAccountName2 -notin $Array){
Write-Host "$sAMAccountName2 does not exist :-)"
}
else{
Write-Host "$sAMAccountName2 does exist :-("
}
Thank you for your help.
Greetings,
PalimPalim

This may do what you need :
$Nachname = "Nachname"
$Vorname = "Vorname"
#$sAMAccountName = $Nachname+$Vorname
$Array = #('NachnameV','NachnameVo','NachnameVor')
$i = 0
do {
$i++
$sAMAccountName = $Nachname+$Vorname.Substring(0,$i)
write-host "i = $i"
write-host "account name = $sAMAccountName"
if($sAMAccountName -in $Array){
Write-Host "$sAMAccountName found"
}
} until ($sAMAccountName -notin $array)
Write-Host "$($Nachname+$Vorname.Substring(0,$i)) not found"
Where $i is used as an index which increases by 1 within the do until loop until the name being searched for no longer shows up in the array.
The write-host lines for i=$i and the account name aren't needed, but just let you see what the script is doing on each iteration round the loop, and can be removed.

Related

Build an interactive menu using powershell

Below script will display the menu and prompt for a selection.However this doesn't give the option to reselect if the selection is made wrong.
I would like to re write in such a way that , it should give the option to confirm the selection and if the selection is made wrong, should give an option to re select from the menu. Is it possible using "do until" loop? Any help is high appreciated
write-host ""
Write-host -ForegroundColor yellow "Choose which Cluster you want to gather ratios on:"
write-host "(it may take a few seconds to build the list)"
write-host ""
$ICLUSTER = get-cluster -server $VIServer | Select-Object Name | Sort-object Name
if ($null -eq $ICLUSTER)
{
Update-log "Unable to find Cluster Information.Please verify the cluster status before proceed `n"
break
}
else
{
$i = 1
$ICLUSTER | %{Write-Host $i":" $_.Name; $i++}
$HCLUSTER = Read-host "Choose the name of cluster you want to select on by entering corresponding number:"
$SCLUSTER = $ICLUSTER[$HCLUSTER -1].Name
Update-log "You have selected $($SCLUSTER). `n"
start-sleep -s 3
}
A loop & couple additional if statements should get you there:
# break the loop by setting $x not equal to 1
$x = 1
While ($x -eq 1){
$ICLUSTER = get-cluster -server $VIServer | Select-Object Name | Sort-object Name
if ($null -eq $ICLUSTER){
Update-log "Unable to find Cluster Information. Please verify the cluster status before proceed `n"
$x = 2
}
else{
$i = 1
$ICLUSTER | %{Write-Host $i":" $_.Name; $i++}
$HCLUSTER = Read-host "Choose the name of cluster you want to select on by entering corresponding number:"
$SCLUSTER = $ICLUSTER[$HCLUSTER -1].Name
if ($SCLUSTER -in $ICLUSTER.Name){
Write-Host "You have selected $($SCLUSTER), do you want to continue?"
$yesno = Read-host "Please type 'Y' to continue or 'N' to quit"
if ($yesno -eq "Y"){
$x = 1
}
else {Write-Host "Quitting"
$x = 2
}
Write-Host "Performing commands"
# Add commands here, to do the work & complete the task
$x = 2
}
elseif (-not($SCLUSTER -in $ICLUSTER.Name)){
Write-Host "Your selection was not found, Would you like to try again?"
$yesno = Read-host "Please type 'Y' to try again or 'N' to quit"
if ($yesno -eq "Y"){
Write-Host "Trying this again"
$x = 1
}
else {Write-Host "Quitting"
$x = 2
}
}
start-sleep -s 3
}
}

Call item from array and run foreach

I'm trying to create a powerhell script which will work through an array and perform an action on each item. But I keep getting an empty value
if ($number -eq "3") {
write-host "vm01 is $(virtualM1)"
$array = $vm01
}
elseif ($number -eq "2") {
write-host "vm01 is $(virtualM1)"
write-host "vm02 is $(virtualM2)"
$array = $vm01,$vm02
}
elseif ($number -eq "3") {
write-host "vm01 is $(virtualM1)"
write-host "vm02 is $(virtualM2)"
write-host "vm03 is $(virtualM3)"
$array = $vm01,$vm02,$vm03
}
elseif ($number -eq "4") {
write-host "vm01 is $(virtualM1)"
write-host "vm02 is $(virtualM2)"
write-host "vm03 is $(virtualM3)"
write-host "vm04 is $(virtualM4)"
$array = $vm01,$vm02,$vm03,$vm04
}
$array | ForEach-Object {$_}
I was thinking you could use $_ and that referenced each object. Can anyone see where I'm going wrong? For something so simple caused tremendous headache :)
Thanks in advance :)

Use PowerShell to find and replace hex values in binary files [duplicate]

This question already has answers here:
delete some sequence of bytes in Powershell [duplicate]
(1 answer)
Methods to hex edit binary files via Powershell
(4 answers)
Closed 3 years ago.
UPDATE:
I got a working script to accomplish the task. I needed to batch process a bunch of files so it accepts a csv file formatted as FileName,OriginalHEX,CorrectedHEX. It's very slow even after limiting the search to the first 512 bytes. It could probably be written better and made faster. Thanks for the help.
UPDATE 2: Revised the search method to be faster but it's nowhere near as fast as a dedicated hex editor. Be aware that it's memory intensive. peaks around 32X the size of the file in RAM. 10MB=320MB of RAM. 100MB=3.2GB of RAM. I don't recommend for big files. It also saves to a new file instead of overwriting. Original file renamed as File.ext_original#date-time.
Import-CSV $PSScriptRoot\HEXCorrection.csv | ForEach-Object {
$File = $_.'FileName'
$Find = $_.'OriginalHEX'
$Replace = $_.'CorrectedHEX'
IF (([System.IO.File]::Exists("$PSScriptRoot\$File"))) {
$Target = (Get-ChildItem -Path $PSScriptRoot\$File)
} ELSE {
Write-Host $File "- File Not Found`n" -ForegroundColor 'Red'
RETURN
}
Write-Host "File: "$Target.Name`n"Find: "$Find`n"Replace: "$Replace
$TargetLWT = $Target.LastWriteTime
$TargetCT = $Target.CreationTime
IF ($Target.IsReadOnly) {
Write-Host $Target.Name "- Is Read-Only`n" -ForegroundColor 'Red'
RETURN
}
$FindLen = $Find.Length
$ReplaceLen = $Replace.Length
$TargetLen = (1..$Target.Length)
IF (!($FindLen %2 -eq 0) -OR !($ReplaceLen %2 -eq 0) -OR
[String]::IsNullOrEmpty($FindLen) -OR [String]::IsNullOrEmpty($ReplaceLen)) {
Write-Host "Input hex values are not even or empty" -ForegroundColor 'DarkRed'
RETURN
} ELSEIF (
$FindLen -ne $ReplaceLen) {
Write-Host "Input hex values are different lengths" -ForegroundColor 'DarkYellow'
RETURN
}
$FindAsBytes = New-Object System.Collections.ArrayList
$Find -split '(.{2})' | ? {$_} | % { $FindAsBytes += [Convert]::ToInt64($_,16) }
$ReplaceAsBytes = New-Object System.Collections.ArrayList
$Replace -split '(.{2})' | ? {$_} | % { $ReplaceAsBytes += [Convert]::ToInt64($_,16) }
# ^-- convert to base 10
Write-Host "Starting Search"
$FileBytes = [IO.File]::ReadAllBytes($Target)
FOREACH ($Byte in $FileBytes) {
$ByteCounter++
IF ($Byte -eq [INT64]$FindAsBytes[0]) { TRY {
(1..([INT64]$FindAsBytes.Count-1)) | % {
$Test = ($FileBytes[[INT64]$ByteCounter-1+[INT64]$_] -eq $FindAsBytes[$_])
IF ($Test -ne 'True') {
THROW
}
}
Write-Host "Found at Byte:" $ByteCounter -ForegroundColor 'Green'
(0..($ReplaceAsBytes.Count-1)) | % {
$FileBytes[[INT64]$ByteCounter+[INT64]$_-1] = $ReplaceAsBytes[$_]}
$Found = 'True'
$BytesReplaces = $BytesReplaces + [INT64]$ReplaceAsBytes.Count
}
CATCH {}
}
}
IF ($Found -eq 'True'){
[IO.File]::WriteAllBytes("$Target-temp", $FileBytes)
$OriginalName = $Target.Name+'_Original'+'#'+(Get-Date).ToString('yyMMdd-HHmmss')
Rename-Item -LiteralPath $Target.FullName -NewName $OriginalName
Rename-Item $Target"-temp" -NewName $Target.Name
#Preserve Last Modified Time
$Target.LastWriteTime = $TargetLWT
$Target.CreationTime = $TargetCT
Write-Host $BytesReplaces "Bytes Replaced" -ForegroundColor 'Green'
Write-Host "Original saved as:" $OriginalName
} ELSE {
Write-Host "No Matches" -ForegroundColor 'Red'}
Write-Host "Finished Search`n"
Remove-Variable -Name * -ErrorAction SilentlyContinue
} # end foreach from line 1
PAUSE
Original: This has been asked before but found no solutions to perform a simple and straight up find hex value and replace hex value on large files, 100MB+.
Even better would be any recommendations for a hex editor with command line support for this task.
Here's a first crack at it:
(get-content -encoding byte file) -replace '\b10\b',11 -as 'byte[]'
I was checking those other links, but the only answer that does search and replace has some bugs. I voted to reopen. The mklement0 one is close. None of them search and then print the position of the replacement.
Nevermind. Yours is faster and uses less memory.

Dynamic input array Powershell

once again I contact you because I am once again having problems with a Powershell script assignment.
My current assignement is to make a script that lets a user put in 1-10 values. The values have to be positive numbers. After that I have to calculate an average of an array.
My idea in this was the following:
clear-host
$averageArray = #()
Write-Host "How many numbers do you want to put in?" -for yellow
Write-Warning "Maximum is 10!"
Write-Host "Press the Enter key to continue."
$amountValues = Read-host
while($amountVAlues -notmatch "^([1-9]|[1][0])$") {
$amountValues = Read-Host "Please enter a number between 1 and 10"
if($amountVAlues -notmatch "^([1-9]|[1][0])$") {Write-host "Error! Please enter a number between 1 and 10!"}
}
$value1 = read-host "Enter number one"
while($value1 -notmatch '^\d+$') {
$value1 = Read-Host
if($value1 -notmatch '^\d+$') {Write-host "Error! Please enter a positive number!"}
}
$value2 = read-host "Enter number two"
while($value2 -notmatch '^\d+$') {
$value2 = Read-Host
if($value2 -notmatch '^\d+$') {Write-host "Error! Please enter a positive number!"}
}
$averageArray = $averageArray + $value1
write-host "$averageArray"
read-host
I created an array, and made the user input a number between 1-10 for the amount of total $values they want in the array. After that I wanted to loop the input of a $value, and input it in the array. I wanted to loop it as many times as the $amountValues variable.
Problem with doing this is that if I would loop it, $variable1 would get overwritten an 'x' amount of times.
Is there any way to input the values via a loop into the array?
I'ld do it like this:
while ( (1..10) -notcontains $g)
{
$g = read-host "How many numbers do you want to put in? (value from 1 to 10) "
}
$ar=#()
for ($i=0; $i -lt $g; $i++)
{
$ar += read-host "Enter value $($i+1)"
}
$averageArray = ($ar | Measure-Object -Average).average
write-host "Average is : $averageArray"

Hash table Get_Item returning blank line - Powershell

$searchterm = read-host “Enter search term for uninstallers”
$uninstallers = get-childitem HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
$founditems = $uninstallers | ? {(Get-ItemProperty -path (“HKLM:\”+$_.name) -name Displayname -erroraction silentlycontinue) -match $searchterm}
write-host “Searched registry for uninstall information on $searchterm”
write-host “——————————————”
$x = 0
$uninstallcommandtable = #{}
$uninstalldisplaytable = #{}
if ($founditems -eq $null) {“None found”} else {
write-host “Found “($founditems | measure-object).count” item(s):`n”
$founditems | % {
$x = $x + 1
Write-host "Item: $x"
Write-host “Displayname: “$_.getvalue(“Displayname”)
Write-host “Displayversion: “$_.getvalue(“Displayversion”)
Write-host “InstallDate: “$_.getvalue(“InstallDate”)
Write-host “InstallSource: “$_.getvalue(“InstallSource”)
Write-host “UninstallString: “$_.getvalue(“UninstallString”)
$uninstallcommandtable.Add($x, $_.getvalue(“UninstallString”))
$uninstalldisplaytable.Add($x, $_.getvalue(“Displayname”))
Write-host “`n”
}
}
Write-host ($uninstalldisplaytable | Out-String)
$whichprogram = read-host "Which program do you want to uninstall?"
Write-host ($uninstallcommandtable.Get_Item($whichprogram) | Out-String)
For some reason the last Write-host is returning a blank line. I verified with a test output just before the last read-host, so I know the $uninstallcommandtable is proper. Any ideas would be great.
Because your hashtable Names are type System.Int32. This will show you that:
$uninstallcommandtable.Keys | % {$_.GetType().FullName}
Read-Host is setting a variable of type System.String. So you will need to convert the string to an System.Int32 like this:
Write-host $uninstallcommandtable.Get_Item([Int32] $whichprogram)
You can also use:
Write-host $uninstallcommandtable.Item([Int32] $whichprogram)
Alternatively, you can make the key a string when you create the hash entry:
$uninstallcommandtable.Add("$x", $_.getvalue(“UninstallString”))