I'm attempting to write a powershell script and running into a problem that google can't seem to tell me how to fix. Basically, i have 4 variables:
$myDuration = $myObj.Duration
$mySubject = $myObj.Subject
$myStart = $myObj.Start
$myLocation = $myObj.Location
I'm trying to send an email where the body is:
"Your meeting ({0}) will begin {1}. It will be held at {2} and last approximately {3}." -f $mySubject,$myStart,$myLocation,$myDuration
Now, if I ONLY include one variable, it works just fine. For example, "Your meeting {0}" -f $myLocation correctly outputs the value stored in $myLocation.
WHen I include more then one, my output for each variable is the exact string "System.Object[]". (IE "Your meeting (System.Object[]) will begin System.Object[]. It will be held at System.Object[] and last approximately System.Object[].") Any ideas why it bugs when I include more then one variable? From everything I've read about on Google there shouldn't be an issue.
Thank you for your time. Editing for hopefully better clarification of my issue.
I suspect that one or more of the fields in $myObj is something other than a string and can't be converted to a string easily, and that's throwing the formatter off. Have a look at this code:
$myDuration = "Duration";
$mySubject = "Subject";
$myStart = "Starttime";
$myLocation = "Location";
"Your meeting ({0}) will begin {1}. It will be held at {2} and last approximately {3}." -f $mySubject,$myStart,$myLocation,$myDuration
$myObj = #{"Duration"=[int32]123456;"Subject"="Subject2";"Starttime"=(get-date);"Location"="Location2"};
$myDuration = $myObj.Duration;
$mySubject = $myObj.Subject;
$myStart = $myObj.Starttime;
$myLocation = $myObj.Location;
"Your meeting ({0}) will begin {1}. It will be held at {2} and last approximately {3}." -f $mySubject,$myStart,$myLocation,$myDuration
And my output is:
Your meeting (Subject) will begin Starttime. It will be held at Location and last approximately Duration.
Your meeting (Subject2) will begin 2/13/2014 10:30:39 PM. It will be held at Location2 and last approximately 123456.
It all works as expected.
Related
I try to update users AD accounts properties with values imported from csv file.
The problem is that some of the properties like department allow strings of length of max length 64 that is less than provided in the file which can be up to 110.
I have found and adopted solution provided by TroyBramley in this thread - How to replace multiple strings in a file using PowerShell (thank You Troy).
It works fine but... Well. After all replaces have place the text is less meaningful than originally.
For example, original text First Department of something1 something2 something3 something4 would result in 1st Dept of sth1 sth2 sth3 sth4
I'd like to have control over the process so I can stop it when the length of the string drops just under the limit alowed by AD property.
By the way. I'd like to have a choice which replacement takes first, second and so on, too.
I put elements in a hashtable alphabetically but it seems that they are not processed this way. I can't figure out the pattern.
I can see the resolution by replacing strings one by one, controlling length after each replacement. But with almost 70 strings it leds to huge portion of code. Maybe there is simpler way?
You can iterate the replacement list until the string reaches the MaxLength defined.
## Q:\Test\2018\06\26\SO_51042611.ps1
$Original = "First Department of something1 something2 something3 something4"
$list = New-Object System.Collections.Specialized.OrderedDictionary
$list.Add("First","1st")
$list.Add("Department","Dept")
$list.Add("something1","sth1")
$list.Add("something2","sth2")
$list.Add("something3","sth3")
$list.Add("something4","sth4")
$MaxLength = 40
ForEach ($Item in $list.GetEnumerator()){
$Original = $Original -Replace $Item.Key,$Item.Value
If ($Original.Length -le $MaxLength){Break}
}
"{0}: {1}" -f $Original.Length,$Original
Sample output with $MaxLength set to 40
37: 1st Dept of sth1 sth2 sth3 something4
I found the below code (untouched) in this forum which is very close to what i was looking for however am having some issues when tweaking;
data Millenium_Falcon;
han='1';
luke='0';
darth='0';
run;
filename myemail EMAIL
to="me#lando.com"
cc="me#lando.com"
from="me#lando.com"
subject="Millenium Falcon"
importance="HIGH"
;
data _null_;
set Millenium_Falcon ;
file myemail;
IF (Luke = '1' and Darth = '0') then do;
put "Han,";
put " ";
put "Look out for the asteroids.";
put " ";
put "Thank you.";
put " ";
put "Obi";
end;
else do;
put '!EM_ABORT!';
end;
stop;
run;
Before tweaking, this code works fine however when i try to point to my data set (removing Millennium_Falcon step above) which just contains meta data from dictionary.tables (libname,memname,modate) and change the if statement to
IF (memname = 'TEST' and datepart(modate) = date()) then do;
the email does not send. It is almost like the data step (below) must be present (acting like datalines) for this to work.
data Millenium_Falcon;
han='1';
luke='0';
darth='0';
run;
Any help would be much appreciated.
Many thanks
Aaron
You probably want something more like this that will abort when no records meet the criteria and otherwise generate a list of the values that do.
data _null_;
file myemail;
if _n_=1 and eof then put '!EM_ABORT!';
set have end=eof ;
where (memname = 'TEST' and datepart(modate) = date()) ;
put memname= modate= ;
run;
I want to grab lots of text content from a .sql file between a --Start and --End comment.
Whatever I do somehow I don`t get the substring method correctly to grab only the text within the --Start and --End comment:
text.sql
This text I want not
--Start
this text I want here
--End
This text I want not
This is what I tried:
$insertStartComment = "--Start"
$insertEndComment = "--End"
$content = [IO.File]::ReadAllText("C:\temp\test.sql")
$insertStartPosition = $content.IndexOf($insertStartComment) + $insertStartComment.Length
$insertEndPosition = $content.IndexOf($insertEndComment)
$content1 = $content.Substring($insertStartPosition, $content1.Length - $insertEndPosition)
$content = $content1.Substring(0,$content1.Length - $insertEndPosition)
It would be nice if someone could help me out find my error :-)
There's an attempt to use uninitialized variable in the code:
$content1 = $content.Substring($insertStartPosition, $content1.Length - $insertEndPosition)
The variable $content1 isn't initialized yet, thus the substring call goes haywire. When you run the code again, the variable is set - and results are even more weird.
Use Powershell's Set-StrictMode to enable warnings about uninitialized variables.
It's not the substring approach you are looking for, but I figured that I would toss out a RegEx solution. This will find the text between the --Start and --End on a text file. In this case, I am grouping the matched text with a named capture called LineYouWant and display the matches that it finds. This also works if you have multiple instances of --Start--End blocks in a single file.
$Text = [IO.File]::ReadAllText("C:\users\proxb\desktop\SQL.txt")
[regex]::Matches($Text,'.*--Start\s+(?<LineYouWant>.*)\s+--End.*') | ForEach {
$_.Groups['LineYouWant'].Value
}
I've been given the scut job of correcting some hundred or so code testing reports that have been filled out incorrectly by a senior coder who has more import work to do.
Unluckily for me all the files are ms-word documents. But luckily for the formatting is all the same and the errors are all made in the same cells in the same table.
In the past I wrote a bash to edit to change single quotes to double quotes on multiple xml files. But that was with a linux machine. This time around I have only a window machine.
Any hints where to begin?
The answer was to use VBA. I built two subroutines.
The first subRoutine loops through the directory and
opens each *.doc file it finds. Then on the open document file it calls
the second subRoutine. After the second subRoutine is finished the document
is saved and then closed.
Sub DoVBRoutineNow()
Dim file
Dim path As String
path = "C:\Documents and Settings\userName\My Documents\myWorkFolder\"
file = Dir(path & "*.doc")
Do While file <> ""
Documents.Open FileName:=path & file
Call editCellsTableRow2
ActiveDocument.Save
ActiveDocument.Close
file = Dir()
Loop
End Sub
~~~~~~
The second subRoutine only works if all documents have the same formating.
For example: The second row of the only table in the document has cells numbered 6, 7, 8. These contain "dd/MM/yyyy" , "Last Name", "First Name"
These cells need to be changed to "yyyy/MM/dd", "Surname", "Given Name"
Sub editCellsTableRow2()
Application.ScreenUpdating = False
Dim Tbl As Table, cel As Cell, i As Long, n As Long
With ActiveDocument
For Each Tbl In .Tables
Tbl.Rows(2).Alignment = xlCenter
For Each cel In Tbl.Rows(2).Cells
If cel.ColumnIndex = 6 Then
cel.Range.Text = vbCrLf + "yyyy/MM/dd"
End If
If cel.ColumnIndex = 7 Then
cel.Range.Text = vbCrLf + "Surname"
End If
If cel.ColumnIndex = 8 Then
cel.Range.Text = vbCrLf + "Given Name"
End If
Next cel
Next Tbl
End With
Set cel = Nothing: Set Tbl = Nothing
Application.ScreenUpdating = True
End Sub
I'm trying to use Powershell to remove all sentences flagged by the Microsoft Word Grammar Checker. I got pretty far looking at the Office Word 2010 Word Object Model. I was able to find the next grammatical incorrect sentence in a document, and was able to delete it. My only problem now is to loop through a document and to delete all of sentences flagged by Microsoft Word Grammar Checker. Here's what I have so far.
cd c:\testruns\
$docPath = "" + $(Get-Location) + "\Grammar\document.docx"
$Word = New-Object -ComObject Word.Application
$Word.Visible = $True
$doc = $Word.documents.open($docPath)
$docSelection = $Word.selection
# Word Method Constants
$wdGoToSpellingError = 13
$wdGoToGrammaticalError = 14
$wdGoToFirst = 1
$wdGoToLast = -1
$wdGoToNext = 2
while (!$AnymoreGrammar) {
[void]$docSelection.GoTo($wdGoToGrammaticalError, $wdGoToNext).delete()
}
Of course the variable $AnymoreGrammar is just pseudocode for a boolean variable that I want to find. I need a valid boolean test in the while loop that checks to see if the document has anymore grammatical errors. If I don't, than the $wdGoToNext will keep going even if there's no grammatical errors. It deletes the first sentence's letter if it can't find a sentence that's flagged with a grammatical error. Any help? I'm using this as a reference.
(http://msdn.microsoft.com/en-us/library/microsoft.office.interop.word.wdgotoitem.aspx)
The problem is that your $docSelection is not updated. What you do is delete a sentence and then delete the very same sentence from the very same selection again and again and again. You need to update $docSelection after each deletion, like this:
while (!$AnymoreGrammar) {
$docSelection.GoTo($wdGoToGrammaticalError, $wdGoToNext).delete()
$docSelection = $Word.selection
}
It deleted everything from the doc for me, but at least it's looping now
Ended up solving it a bit ago. Found a ProofreadingError object that contains a property called Count that returns the number of GrammaticalErrors. (msdn.microsoft.com/en-us/library/aa213190(v=office.11).aspx)
So I set the While Loop test to
$errorCount = $doc.GrammaticalErrors.Count
while ($errorCount -ne 0)