INI file editing, Save format - powershell

So i have a working code. i just learned about this today but am wondering if there is a way to save the formatting. (found it on here btw).
$ini = Get-IniContent c:\temp\ini.ini
$ini["posscreen"]["BitmapFile"] = "C:\Temp\FileC.bmp"
$ini | Out-IniFile -FilePath c:\temp\ini2.ini
This is how it looks normally:
[ShapePageFnt]
Position=1.73 -2.76 -15.00
Scale=0.35 0.36 0.38
ZoneDepth=0
StringLength=9600
Font=VerdanaBold
Color=0xFF000000
Kerning=0.270000
String=1/10
StringAlignment=Left
[sgcArialBlack]
FontFile=ArialBlack.png
DataFile=ArialBlack.ftd
StringLength=0
StringStack=0
StringAlignment=Center
Kerning=0.25
Color=0xFF00AAFF
Position=0 0 -1000
Dimension=1 1
Scale=1 1 1
String=
[sgcXtraLabel]
Position=-3.25 -5.61 -15.00
Dimension=1.00 1.00
Scale=0.33 0.33 0.33
ZoneDepth=-101
StringLength=20
Font=VerdanaBold
Color=0xFFFFFFFF
String=Xtra Games
StringAlignment=Center
After running the code:
[ShapePageFnt]
Position=1.73 -2.76 -15.00
Scale=0.35 0.36 0.38
ZoneDepth=0
StringLength=9600
Font=VerdanaBold
Color=0xFF000000
Kerning=0.270000
String=1/10
StringAlignment=Left
[sgcArialBlack]
FontFile=ArialBlack.png
DataFile=ArialBlack.ftd
StringLength=0
StringStack=0
StringAlignment=Center
Kerning=0.25
Color=0xFF00AAFF
Position=0 0 -1000
Dimension=1 1
Scale=1 1 1
String=
[sgcXtraLabel]
Position=-3.25 -5.61 -15.00
Dimension=1.00 1.00
Scale=0.33 0.33 0.33
ZoneDepth=-101
StringLength=20
Font=VerdanaBold
Color=0xFFFFFFFF
String=Xtra Games
StringAlignment=Center
Any help would be appreciated.
** i tried -format and -table just for kicks and didn't do anything but pop up errors.**
Is there a /? for stuff in power shell to check if these conditions are even available?
End goal: to have the code ran and have it output the same way it inputs with the spaces. (the code replaces a set item in the .ini)

I downloaded the script and had a look at the parameters for the Out-IniFile function. I found two switch parameters there:
Pretty which adds an extra linebreak between Sections
Loose which adds spaces around the equal sign when writing the key = value
To use them, your command to write the ini file would be:
$ini | Out-IniFile -FilePath c:\temp\ini2.ini -Pretty -Loose
The author of that script forgot to add descriptions of the parameters in the comment-based help info, so that's why Get-Help didn't show it..

I am unable to comment on the other answer, as I don't have enough reputation points.
#Theo answer is correct; with the exception that the 2 parameters are indeed documented:
https://github.com/lipkau/PsIni/blob/master/PSIni/Functions/Out-IniFile.ps1#L98-L106
I ♥ PS> help Out-IniFile -Parameter pretty, loose
-Pretty [<SwitchParameter>]
Writes the file as "pretty" as possible
Adds an extra linebreak between Sections
Required? false
Position? named
Default value False
Accept pipeline input? false
Accept wildcard characters? false
-Loose [<SwitchParameter>]
Adds spaces around the equal sign when writing the key = value
Required? false
Position? named
Default value False
Accept pipeline input? false
Accept wildcard characters? false
Also, the git repository of that module is https://github.com/lipkau/PsIni.
You can create issues there for missing functionality or general questions

Related

Powershell: Compare filenames to a list of formats

I am not looking for a working solution but rather an idea to push me in the right direction as I was thrown a curveball I am not sure how to tackle.
Recently I wrote a script that used split command to check the first part of the file against the folder name. This was successful so now there is a new ask: check all the files against the naming matrix, problem is there are like 50+ file formats on the list.
So for example format of a document would be ID-someID-otherID-date.xls
So for example 12345678-xxxx-1234abc.xls as a format for the amount of characters to see if files have the correct amount of characters in each section to spot typos etc.
Is there any other reasonable way of tackling that besides Regex? I was thinking of using multiple splits using the hyphens but don't really have anything to reference that against other than the amount of characters required in each part.
As always, any (even vague) pointers are most welcome ;-)
Although I would use a regex (as also commented by zett42), there is indeed an other way which is using the ConvertFrom-String cmdlet with a template:
$template = #'
{[Int]Some*:12345678}-{[String]Other:xxxx}-{[DateTime]Date:2022-11-18}.xls
{[Int]Some*:87654321}-{[String]Other:yyyy}-{[DateTime]Date:18Nov2022}.xls
'#
'23565679-iRon-7Oct1963.xls' | ConvertFrom-String -TemplateContent $template
Some : 23565679
Other : iRon
Date : 10/7/1963 12:00:00 AM
RunspaceId : 3bf191e9-8077-4577-8372-e77da6d5f38d

Leading 0 removed from argument in Powershell

New to Powershell, never needed it before I started this job. I'm just making an easier way for me to keep our stores pinging and kill some time learning. Some pretext; Our stores are always 4 numbers, so 1096 is 1096 but 704 is 0704.
Here is my current script:
$args.Length;
foreach ($arg in $args) {
Test-Connection $arg'router' }
Write-Host 'Pinging Store #'$arg
if($arg.legnth -lt 4) {
($arg).insert(0,'0')
}
If I execute with the argument 1096 all is well in the world, but if I use 0704 the leading 0 disappears. I've tried a number of potential resolutions, but I've found most are trying to remove trailing zeroes so I've just been trying to reverse engineer their solutions. What is the best way to ensure that the leading 0 isn't removed so the host is able to be found.
0704router exists.
704router doesn't exist.
This looks like an issue of how you call the script. You may be doing something like this:
./MyScript.ps1 1096 0704
Which will give you 2 arguments, but since they are unquoted and contain only digits, they are interpreted as integers, and so you lose leading zeros.
Instead, tell PowerShell you want these as string values by quoting them:
./MyScript.ps1 '1096' '0704'
The [string]$Args[1] worked for me and
it seems like the behavior is changing from version to version - same script worked without conversion with PS 2.0
Hope this helps!

Sending complex, multi-line command via plink to Cisco Router =Unexplained behavior

I'm trying to get the below part of the code done in a relatively condensed fashion (to plug in to a much bigger script). I don't have any problems sending multiple commands this way. However, there's something that's causing the multi-line command to eventually choke. Syntax for Cisco comnmands appear to be correct. I'm not sure if I'm running into some kind of character limit or if I need to escape specific characters in $showintstatusCommands, but nothing I tried seems to work.
This code:
$BGPInterface = "GigabitEthernet0/2"
$showintstatusCommands = "`nterminal length 0`nsho int $BGPInterface | include reliability|errors`nsho log | include $Date.*LINK-3-UPDOWN.*$BGPInterface`nexit"
($Response = $showintstatusCommands | C:\Windows\plink.exe -ssh -2 -l $Credential.GetNetworkCredential().username -pw $($Credential.GetNetworkCredential().password) $DeviceName -batch) 2>$null | out-null
produces the below when I reveal the contents of the variables. $ShowIntstatusCommands appears to be correct when it echoes locally. Notice, the end of the 3rd line is cut off (number 2 character is missing at the end). Also the subsequent line is some weird residual of the previous line, which starts with $nclude.
PS C:\Users\MKANET\Desktop\test> $Response
CISCO-ROUTER#
CISCO-ROUTER#terminal length 0
CISCO-ROUTER#sho int GigabitEthernet0/2 | include reliability|errors
reliability 255/255, txload 1/255, rxload 1/255
0 input errors, 0 CRC, 0 frame, 0 overrun, 0 ignored
0 output errors, 0 collisions, 3 interface resets
CISCO-ROUTER#sho log | include Jul 17.*LINK-3-UPDOWN.*GigabitEthernet0/
$nclude Jul 17.*LINK-3-UPDOWN.*GigabitEthernet0/2
CISCO-ROUTER#
CISCO-ROUTER#exit
PS C:\Users\MKANET\Desktop\test> $showintstatusCommands
terminal length 0
sho int GigabitEthernet0/2 | include reliability|errors
sho log | include Jul 17.*LINK-3-UPDOWN.*GigabitEthernet0/2
exit
When you write to a variable in a non-global scope (like script or function scope), PowerShell will not modify any higher level scoped variables of the same name. IOW $Response = 'foo' will create a local copy of the $Response variable and assign 'foo' to it. If your intent is to modify the global variable $Response then change the line to $global:Response = ... What you see in $global:Response is residual, probably from previous tinkerings.
I finally verified that the same behavior was happening on all the remote devices if I typed in the command below manually. The line get's jumbled up if too many characters were used.
I changed:
sho log | include $Date.*LINK-3-UPDOWN.*$BGPInterface
to the below command (removing just a couple of characters); and, it worked fine. It looks like it was a Cisco IOS CLI limit.
sho log | include $Date.*LINK-3-UPDO.*$BGPInterface

Powershell break a file up on character count

I have a binary file that I need to process, but it contains no line breaks in it.
The data is arranged, within the file, into 104 character blocks and then divided into its various fields by character count alone (no delimiting characters).
I'd like to firstly process the file, so that there is a line break (`n) every 104 characters, but after much web searching and a lot of disappointment, I've found nothing useful yet. (Unless I ditch PowerShell and use awk.)
Is there a Split option that understands character counts?
Not only would it allow me to create the file with nice easy to read lines of 104 chars, but it would also allow me to then split these lines into their component fields.
Can anyone help please, without *nix options?
Cheers :)
$s = get-content YourFileName | Out-String
$a = $s.ToCharArray()
$a[0..103] # will return an array of first 104 chars
You can get your string back the following way, the replace removes space char( which is what array element separators turn into)
$ns = ([string]$a[0..103]).replace(" ","")
Using the V4 Where method with Split option:
$text = 'abcdefghi'
While ($text)
{
$x,$text = ([char[]]$text).where({$_},'Split',3)
$x -join ''
}
abc
def
ghi

how to use expressions as function parameters in powershell

This is a very simple task in every language I have ever used, but I can't seem to figure it out in PowerShell. An example of what I'm talking about in C:
abs(x + y)
The expression x + y is evaluated, and the result passed to abs as the parameter... how do I do that in PowerShell? The only way I have figured out so far is to create a temporary variable to store the result of the expression, and pass that.
PowerShell seems to have very strange grammar and parsing rules that are constantly catching me by surprise, just like this situation. Does anyone know of documentation or a tutorial that explains the basic underlying theory of the language? I can't believe these are all special cases, there must be some rhyme or reason that no tutorial I have yet read explains. And yes, I've read this question, and all of those tutorials are awful. I've pretty much been relegated to learning from existing code.
In your case, simply surrounding the expression with parenthesis will allow you to pass it to your function.
You need to do this because PowerShell has more than one parsing mode depending on the beginning of the command.
Expression mode is similar to how most other languages parse - numbers are numbers and strings are quoted.
Command mode treats everything as a string except for variables and parenthesis. Strings here don't need to be quoted.
1+2 Expression mode - starts with number
"string" Expression mode - starts with quote
string Command mode - starts with letter
& "string" Command mode - starts with &
. "string" Command mode - starts with . and a space
.123 Expression mode - starts with . and number (without space)
.string Command mode - starts with a . that is part of a command name
You can mix modes in a single line by enclosing the commands with parenthesis.
You can see this effect if you define function abs in the following way:
function Abs($value)
{
Write-Host $args
if($value -lt 0) { -$value } else { $value }
}
Abs 1 + 2
#Prints: + 2
#Returns: 1
Abs 1+2
#Prints:
#Returns: 1+2
Abs (1 + 2)
#Prints:
#Returns: 3
Abs (1+2)
#Prints:
#Returns: 3
Not sure I follow exactly the problem you are encountering. The following shows that this works as expected in PowerShell:
PS> function abs($val) {Write-Host "`$val is $val"; if ($val -ge 0) {$val} `
else {-$val}}
PS> abs (3+4)
$val is 7
7
As for the best docs on the language, I highly recommend Windows PowerShell in Action by Bruce Payette (he's the guy behind the grammar). If you can wait a few more months (or are OK with an eletronic copy), there is a second edition due out this summer that has been updated for PowerShell 2.0.
You may also find my Effective PowerShell series helpful. Checkout item #10 on PowerShell Parsing Modes.