Loading .msg file contents Using Powershell - Null Value error - powershell

I am trying to access the metadata in a .msg file using Powershell (for example, get the sender address, subject line etc)
I have the following, simple code
Add-Type -assembly "Microsoft.Office.Interop.Outlook"
$outlook = New-Object -comObject Outlook.Application
$msg = $outlook.Session.OpenSharedItem("C:\Test\email.msg")
but I get the error
You cannot call a method on a null-valued expression. At line:4 char:1
If I run
$outlook
I get
Application :
Class :
Session :
Parent :
Assistant :
Name :
Version :
COMAddIns :
Explorers :
Inspectors :
LanguageSettings :
ProductCode :
AnswerWizard :
FeatureInstall :
Reminders :
DefaultProfileName :
IsTrusted :
Assistance :
TimeZones :
PickerDialog :
all the properties appear to be null, including .Session, which explains why I get the null value error.
What have I done wrong in creating the $outlook object?
I have tried with both Outlook running and not running and the same happens.
I have Office 365 installed and I'm using Powershell 5.1.19041.1320

I managed to fix this issue by doing a "Quick Repair" of O365 in the programs and features dialog

On Windows 10 Pro and "Microsoft 365 Apps for Business," Quick Repair also worked for me 7/15/2022 when my similar script which creates a CVS export of selected Outlook Contacts stopped working, for the same reason, namely that the assignment to $outlook completed normally, but then $outlook had no parameter values, just as you show above, leading to the same null-valued expression error.
I had not run the script for a month or more, so can't say which or what kind of update broke it.
Here is an example of a valid value for $outlook, after repair (I set Product Code to all 0s in case that value identifies my license):
Application : Microsoft.Office.Interop.Outlook.ApplicationClass
Class : olApplication
Session : Microsoft.Office.Interop.Outlook.NameSpaceClass
Parent :
Assistant : System.__ComObject
Name : Outlook
Version : 16.0.0.15330
COMAddIns : System.__ComObject
Explorers : {}
Inspectors : {System.__ComObject, System.__ComObject, System.__ComObject, System.__ComObject...}
LanguageSettings : System.__ComObject
ProductCode : {00000000-0000-0000-0000-000000000000}
AnswerWizard :
FeatureInstall : msoFeatureInstallOnDemand
Reminders : {$null, $null, $null, $null...}
DefaultProfileName : MS-2017-10
IsTrusted : False
Assistance : System.__ComObject
TimeZones : {System.__ComObject, System.__ComObject, System.__ComObject, System.__ComObject...}
PickerDialog : System.__ComObject

Related

How to get Display Name from an installer file in powershell

I'm trying to install a software in my computer using Powershell script.
Before install, I want to check if my installer file version is newer than the installed program.
For the installed program I can get the DisplayName, Version, etc...
but I need to get the DisplayName of the installer file before to make some queries with this DisplayName.
For instance
I have installed npp.7.9.5.Installer.x64 (Version 7.9.5) and
I want to install npp.8.1.7.Installer.x64 (Version 8.1.7)
I can get version and name with this, (for the installed programs in my computer).
Get-WmiObject -Class Win32_Product | select Name, Version
But I want to know if I can get the same info from my npp.8.1.7.Installer.x64.exe file, (something like extract info from the installer)
The developers of Notepad++ seem to do a good job. They do put the proper version number to the installer file. So you can easily get the information with PowerShell by getting the properties of the installer file like this:
$NPPInstallerFile = Get-Item -Path 'D:\olaf\Downloads\npp.8.1.7.Installer.x64.exe'
$NPPInstallerFile.VersionInfo.FileVersion
$NPPInstallerFile.VersionInfo.ProductVersion
That provides an output like this:
8.1.7.0
8.17
In addition to Olaf's answer you can do
$NPPInstallerFile = Get-Item -Path 'D:\Downloads\npp.8.1.7.Installer.x64.exe'
$NPPInstallerFile.VersionInfo | Format-List *
To see all info of the version like:
FileVersionRaw : 8.1.7.0
ProductVersionRaw : 8.1.7.0
Comments :
CompanyName : Don HO don.h#free.fr
FileBuildPart : 7
FileDescription : Notepad++ : a free (GNU) source code editor
FileMajorPart : 8
FileMinorPart : 1
FileName : D:\Downloads\npp.8.1.7.Installer.x64.exe
FilePrivatePart : 0
FileVersion : 8.1.7.0
InternalName :
IsDebug : False
IsPatched : False
IsPrivateBuild : False
IsPreRelease : False
IsSpecialBuild : False
Language : Engels (Verenigde Staten)
LegalCopyright : Copyleft 1998-2017 by Don HO
LegalTrademarks :
OriginalFilename :
PrivateBuild :
ProductBuildPart : 7
ProductMajorPart : 8
ProductMinorPart : 1
ProductName : Notepad++
ProductPrivatePart : 0
ProductVersion : 8.17
SpecialBuild :
There is no DisplayName property.. Perhaps you want the FileDescription or ProductName ?

Getting property values from MSI file using PowerShell

I am adding property information to our MSI built using WiX 3.11. I am referring to the properties you find when right-clicking on a file and selecting Properties:
In the Product.wxs file I am setting these values like so:
<Product Id="$(var.ProductCode)"
Name="$(var.ProductName) $(var.ShortAssyVersion)"
Language="1033"
Version="$(var.LongAssyVersion)"
Manufacturer="$(var.CompanyLegalName)"
UpgradeCode="$(var.UpgradeCode)">
<Package Description="Installation Package"
InstallerVersion="300"
Compressed="yes"
InstallScope="perMachine"
InstallPrivileges="elevated"
Comments="$(var.LongAssyVersion)" />
I would like to use some of these values in an automated build script and am trying to retrieve the values using PowerShell get-item. When I run this command in PowerShell:
PS C:\Subversion\MyProduct\Publish> (get-item "Setup.msi").VersionInfo | fl
this is the output:
OriginalFilename :
FileDescription :
ProductName :
Comments :
CompanyName :
FileName : C:\Subversion\MyProduct\Publish\Setup.msi
FileVersion :
ProductVersion :
IsDebug : False
IsPatched : False
IsPreRelease : False
IsPrivateBuild : False
IsSpecialBuild : False
Language :
LegalCopyright :
LegalTrademarks :
PrivateBuild :
SpecialBuild :
FileVersionRaw : 0.0.0.0
ProductVersionRaw : 0.0.0.0
How can I retrieve these values (i.e., Comments, Date Created, etc.) from the file properties for use in a PowerShell script?

IIS Administration from TFS Release automation - PowerShell script fails Get-ChildItem -Path IIS:\Sites

I'm having difficulty in using the Powershell WebAdministration Module with Powershell 5.1.
This is on a Server 2008R2 machine, running IIS 7.5
There seems to be an issue with this module in that occasionally the module requires a few ms to complete initialization after loading. The recommendation is to do a simple 'write-output' after loading to allow the server to complete the init tasks. I dont see it on all the servers I'm managing, but this particular server is consistent in its need.
There's also an issue that I found people had with Get-Sites failing that could be dealt with by wrapping in a try/catch.
However, the problem I'm seeing is that even with the identified workarounds, I'm not getting consistent results between an interactive run, and a run that is performed from TFS Automated release.
Import-Module WebAdministration
$sites="none"
Write-Output "suggested as a work around for the task dying for no apparent reason"
try {
$sites = Get-ChildItem -Path IIS:\Sites
Write-Output "part of try"
} catch {
$sites = Get-ChildItem -Path IIS:\Sites
Write-Output "part of catch"
} finally {
Write-Output $sites
Write-Output $sites.GetType()
}
When run via TFS Release automation (agent version 2.117.2, PowerShell on the target machine version 1.0.47):
2018-01-25T13:18:29.5474995Z Importing alias 'End-WebCommitDelay'.
2018-01-25T13:18:29.5474995Z
2018-01-25T13:18:29.5474995Z suggested as a work around for the task dying for no apparent reason
2018-01-25T13:18:29.5474995Z part of catch
2018-01-25T13:18:29.5474995Z
2018-01-25T13:18:29.5474995Z
2018-01-25T13:18:29.5631000Z Deployment status for machine 'DESTSERV:5985' : 'Passed'
(no sitelist is returned)
When run as an interactive process (with same user)
PS C:\Users\Install> C:\Installers\Modules\test-iis.ps1
suggested as a work around for the task dying for no apparent reason
part of try
Name ID State Physical Path Bindings
---- -- ----- ------------- --------
AppTest 2 Started E:\WebApps\AppTest http *:80:
https *:443:
Test 1 Stopped C:\inetpub\wwwroot\Test http *:80:
https
Module : CommonLanguageRuntimeLibrary
Assembly : mscorlib, Version=4.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089
TypeHandle : System.RuntimeTypeHandle
DeclaringMethod :
BaseType : System.Array
UnderlyingSystemType : System.Object[]
FullName : System.Object[]
AssemblyQualifiedName : System.Object[], mscorlib, Version=4.0.0.0,
Culture=neutral,
PublicKeyToken=b77a5c561934e089
Namespace : System
GUID : 00000000-0000-0000-0000-000000000000
IsEnum : False
GenericParameterAttributes :
IsSecurityCritical : False
IsSecuritySafeCritical : False
IsSecurityTransparent : True
IsGenericTypeDefinition : False
IsGenericParameter : False
GenericParameterPosition :
IsGenericType : False
IsConstructedGenericType : False
ContainsGenericParameters : False
StructLayoutAttribute :
Name : Object[]
MemberType : TypeInfo
DeclaringType :
ReflectedType :
MetadataToken : 33554432
GenericTypeParameters : {}
DeclaredConstructors : {Void .ctor(Int32)}
DeclaredEvents : {}
DeclaredFields : {}
DeclaredMembers : {Void Set(Int32, System.Object), System.Object&
Address(Int32), System.Object Get(Int32),
Void .ctor(Int32)}
DeclaredMethods : {Void Set(Int32, System.Object), System.Object&
Address(Int32), System.Object Get(Int32)}
DeclaredNestedTypes : {}
DeclaredProperties : {}
ImplementedInterfaces : {System.ICloneable, System.Collections.IList,
System.Collections.ICollection,
System.Collections.IEnumerable...}
TypeInitializer :
IsNested : False
Attributes : AutoLayout, AnsiClass, Class, Public, Sealed,
Serializable
IsVisible : True
IsNotPublic : False
IsPublic : True
IsNestedPublic : False
IsNestedPrivate : False
IsNestedFamily : False
IsNestedAssembly : False
IsNestedFamANDAssem : False
IsNestedFamORAssem : False
IsAutoLayout : True
IsLayoutSequential : False
IsExplicitLayout : False
IsClass : True
IsInterface : False
IsValueType : False
IsAbstract : False
IsSealed : True
IsSpecialName : False
IsImport : False
IsSerializable : True
IsAnsiClass : True
IsUnicodeClass : False
IsAutoClass : False
IsArray : True
IsByRef : False
IsPointer : False
IsPrimitive : False
IsCOMObject : False
HasElementType : True
IsContextful : False
IsMarshalByRef : False
GenericTypeArguments : {}
CustomAttributes : {[System.SerializableAttribute()]}
PS C:\Users\Install>
When WebAdministration doesn't import properly it seems there is more going wrong than just a slow initialization. The IIS: provider is not functional.. it throws no error. It does return something though - the value set at the top of the script is being overwritten... I just dont get the sites list.
As can be seen by the interactive run, there are sites present, so an empty return value does not make any sense.
Updated:
All the suggested workarounds have been applied yet the Get-ChildItem in the catch fails to produce the sites list. How do I get a consistent result where I can obtain the full list of sites in IIS both interactively and through TFS Release's PowerShell on the target machine task??
I can run the script via TFS Release automation without any error and get the consistent result with the interactive process. (Agent version 2.117.1, PowerShell on the target machine version 5.1.14393.1944).
You need to set the TFS build agent service account as an local administrator account in the target machine (Just add the build agent service account to the local administrators group).
So, please have a try with that. If that still not work, just try to upgrade the PowerShell version on your target machine (may be caused by the PS version). Refer to Install PowerShell 5 in Windows Server 2008 R2 for details.
UPDATE:
Generally, the output of the scripts will not back to build process when run the PS scripts with task PowerShell on the target machines.
You need to update the script to get back the outputs (use Write-Verbose instead of Write-Output ), just try below scripts, it works for me:
Import-Module WebAdministration
$sites="none"
Write-Verbose "suggested as a work around for the task dying for no apparent reason"
try {
$sites = Get-ChildItem -Path IIS:\Sites | Out-String
Write-Verbose "part of try"
} catch {
$sites = Get-ChildItem -Path IIS:\Sites | Out-String
Write-Verbose "part of catch"
} finally {
Write-Verbose $sites -verbose
Write-Verbose $sites.GetType() -verbose
}

No email addresses in outlook ContactItem via powershell

When I examine a ContactItem, all of the Email#Address values are null. I have tried settings the value then printing the value. The change is reflected in Outlook, however, no value can be retrieved via PowerShell.
Below are some snippets:
$Outlook=NEW-OBJECT –comobject Outlook.Application
$Contacts=$Outlook.session.GetDefaultFolder(10).items
$Contactsfolders = $Outlook.session.GetDefaultFolder(10).Folders
$testFolder = $Contactsfolders | Where-Object {$_.Name -eq 'Test Folder'}
$testContact = $testFolder.Items(1)
echo $testContact
$testContact.Email1Address = "BobDoe3#doe.com"
echo $testContact
Here is the output of the above execution. Note I've removed some of the uninteresting information to shorten.
First Echo
Application : Microsoft.Office.Interop.Outlook.ApplicationClass
Class : 40
Session : Microsoft.Office.Interop.Outlook.NameSpaceClass
ConversationTopic : John Doe
FormDescription : System.__ComObject
GetInspector : System.__ComObject
Importance : 1
LastModificationTime : 10/31/2017 5:57:04 PM
MAPIOBJECT : System.__ComObject
MessageClass : IPM.Contact
OutlookInternalVersion : 154971
OutlookVersion : 15.0
Saved : True
Sensitivity : 0
Size : 11614
Subject : Bob Doe
UserProperties : System.__ComObject
Account :
Anniversary : 1/1/4501 12:00:00 AM
AssistantName :
AssistantTelephoneNumber :
Birthday : 1/1/4501 12:00:00 AM
CompanyAndFullName : The Doe Company
Doe, Bob
CompanyLastFirstNoSpace :
CompanyLastFirstSpaceOnly :
CompanyMainTelephoneNumber :
CompanyName : The Doe Company
ComputerNetworkName :
CustomerID :
Department :
Email1Address :
Email1AddressType :
Email1DisplayName :
Email1EntryID :
Email2Address :
Email2AddressType :
Email2DisplayName :
Email2EntryID :
Email3Address :
Email3AddressType :
Email3DisplayName :
Email3EntryID :
FileAs : Doe, Bob
FirstName : Bob
FTPSite :
FullName : Bob Doe
FullNameAndCompany : Doe, Bob
The Doe Company
Gender : 0
GovernmentIDNumber :
Hobby :
Home2TelephoneNumber :
HomeAddress :
HomeAddressCity :
HomeAddressCountry :
HomeAddressPostalCode :
HomeAddressPostOfficeBox :
HomeAddressState :
HomeAddressStreet :
HomeFaxNumber :
HomeTelephoneNumber :
Initials : B.D.
InternetFreeBusyAddress :
ISDNNumber :
JobTitle :
Journal : False
Language :
LastFirstAndSuffix :
LastFirstNoSpace :
LastFirstNoSpaceCompany :
LastFirstSpaceOnly :
LastFirstSpaceOnlyCompany :
LastName : Doe
LastNameAndFirstName : Doe, Bob
Second Echo
Application : Microsoft.Office.Interop.Outlook.ApplicationClass
Class : 40
Session : System.__ComObject
Subject : Bob Doe
UnRead : False
UserProperties : System.__ComObject
Account :
Anniversary : 1/1/4501 12:00:00 AM
AssistantName :
AssistantTelephoneNumber :
Birthday : 1/1/4501 12:00:00 AM
Business2TelephoneNumber :
BusinessAddress :
BusinessAddressCity :
BusinessAddressCountry :
BusinessAddressPostalCode :
BusinessAddressPostOfficeBox :
BusinessAddressState :
BusinessAddressStreet :
BusinessFaxNumber :
BusinessHomePage :
BusinessTelephoneNumber :
CallbackTelephoneNumber :
CarTelephoneNumber :
Children :
CompanyAndFullName : The Doe Company
Doe, Bob
CompanyLastFirstNoSpace :
CompanyLastFirstSpaceOnly :
CompanyMainTelephoneNumber :
CompanyName : The Doe Company
ComputerNetworkName :
CustomerID :
Department :
Email1Address :
Email1AddressType :
Email1DisplayName :
Email1EntryID :
Email2Address :
Email2AddressType :
Email2DisplayName :
Email2EntryID :
Email3Address :
Email3AddressType :
Email3DisplayName :
Email3EntryID :
FileAs : Doe, Bob
FirstName : Bob
FTPSite :
FullName : Bob Doe
FullNameAndCompany : Doe, Bob
The Doe Company
Gender : 0
GovernmentIDNumber :
Hobby :
Home2TelephoneNumber :
HomeAddress :
HomeAddressCity :
HomeAddressCountry :
HomeAddressPostalCode :
HomeAddressPostOfficeBox :
HomeAddressState :
HomeAddressStreet :
HomeFaxNumber :
HomeTelephoneNumber :
Initials : B.D.
InternetFreeBusyAddress :
ISDNNumber :
JobTitle :
Journal : False
Language :
LastFirstAndSuffix :
LastFirstNoSpace :
LastFirstNoSpaceCompany :
LastFirstSpaceOnly :
LastFirstSpaceOnlyCompany :
LastName : Doe
LastNameAndFirstName : Doe, Bob
Something interesting that I've found while playing with different results and solutions.
I've found that both of the below queries results in the same matches which confuses me as I would have thought myString -ne '' is checking if the string is not empty. It appears that myString -ne '' and [String]::IsNullOrEmpty($myString) can both return true which seems impossible, but I think there are some cases where this could happen. Also note that IsNullOrEmpty function is extraordinarily faster.
$Listconstact=$session.GetDefaultFolder(10).Folders | %{$session.GetFolderFromID($_.EntryID).Items | where Email1Address -NE ''}
and
$Listconstact=$session.GetDefaultFolder(10).Folders | %{$session.GetFolderFromID($_.EntryID).Items | where {[String]::IsNullOrEmpty($_.Email1Address)}}
Results from tukan's answer:
VERBOSE: From:
VERBOSE: Subject: How are things
VERBOSE: From:
VERBOSE: Subject: See you soon
VERBOSE: From:
VERBOSE: Subject: Meeting Times
Try Something like this:
$Outlook=NEW-OBJECT –comobject Outlook.Application
$session=$Outlook.session
$Listconstact=$session.GetDefaultFolder(10).Folders | %{$session.GetFolderFromID($_.EntryID).Items | where Email1Address -ne ''}
#only one item
Write-Host "First element mail : $($Listconstact[0].Email1Address)`n`n"
#All mails
Write-Host "All element mail :"
$Listconstact.Email1Address
I'm kind of fuzzy on what you are tying to achieve. To me it seems you are mixing two things together - contacts & folders.
I'm not sure if you are trying to get information from Outlook emails or Address book (since you are using folder I guess it is the first). I'll gladly rectify the solution if it is not solving your issue.
Note: I don't have identical configuration but close enough: Outlook version: 15.0.0.4420 and PowerShell version: 4.0.30319.
I'll try my best to cover what I think you are trying to solve in my eyes - Getting all contacts' email addresses (adding also subject) from received emails in "Test Folder" #Outlook.
# Making sure we have the assembly loaded
Add-Type -assembly "Microsoft.Office.Interop.Outlook"
# saving the mapping
$olFolders = "Microsoft.Office.Interop.Outlook.OlDefaultFolders" -as [type]
# new object
$Outlook=NEW-OBJECT –comobject Outlook.Application
# setting the correct namespace
$namespace = $Outlook.GetNameSpace("MAPI")
# getting all folders in Outlook inbox
$inbox = $namespace.GetDefaultFolder($olFolders::olFolderInbox)
# filtering out all but the "Test Folder"
$targetFolder = $inbox.Folders.Item("Test Folder")
# iteration on email message
ForEach($emailMessage in $targetFolder.items) {
# getting all the information from the message
Write-Verbose -message "From: $($emailMessage.GetProperty) $($emailMessage.SenderEmailAddress)" -Verbose
Write-Verbose -message "Subject: $($emailMessage.Subject)" -Verbose
}
Why MAPI namespace? Well because the MSDN says so.
I would have thought myString -ne '' is checking if the string is not
empty.
Yes it does do that. The difference is that the method [String]::IsNullOrEmpty($myString) is checking for Null OR Empty in a string. In case, when you have a $null value then you can have both true. It is not empty and is $null. (for more see what does it mean to have a $null value)

Powershell: Sorting and display the most recent duplicate in a custom object (by username)

I'm looking for some suggestions/tips on how to sort and display the most recent record in a custom object (by a username). Basically, I am in a situation where I have an ActiveSync report with multiple usernames showing up on the report but I only want the most recent user's device information like device version , last contact time, etc... (See below the custom object's fields)
I've tried the following code but I am not getting the results I am looking for.
$ActiveSyncImport | Group-Object Identity| foreach-object { $_.group | sort-object LastSuccessSync | select -last 1}
Any help would be greatly appreciated
**Update as of 9/10/2013 at 8:40pm MST:
The output I am trying to get is like the following:
DeviceOS DeviceID
-------- --------
ApplDMPFWGAADFHW
Windows Phone7.10.7720 C3F755AAEB6CDE163838A106B00382F8
Android 4.2.2 3939303030303238323236343838
But, when I use my one-line of code I get the same results as my original ActiveSync Information not sorted or grouped.
ActiveSync Information:
RunspaceId : be1d8592-a70a-4322-a146-f6569a067af6
SamAccountName :
FirstSyncTime : 4/8/2013 9:49:31 PM
LastPolicyUpdateTime : 4/8/2013 9:50:41 PM
LastSyncAttemptTime : 9/9/2013 4:06:13 AM
LastSuccessSync : 9/9/2013 4:06:13 AM
DeviceType : iPhone
DeviceID : ApplC39xxxP9DDP7
DeviceUserAgent : Apple-iPhone3C3/1002.329
DeviceWipeSentTime :
DeviceWipeRequestTime :
DeviceWipeAckTime :
LastPingHeartbeat : 900
RecoveryPassword : ********
DeviceModel : iPhone3C3
DeviceImei :
DeviceFriendlyName : Black iPhone 4
DeviceOS : iOS 6.1.3 10B329
DeviceOSLanguage : en
DevicePhoneNumber :
MailboxLogReport :
DeviceEnableOutboundSMS : False
DeviceMobileOperator :
Identity : corp.XXXX.com/NorthAmerica/Users/lastname, firstname/ExchangeActiveSyncDevices/iPhone§ApplC39xxxP9DDP7
Guid : e7712106-3643-XXXX-XXXX-e20fa4376ad9
IsRemoteWipeSupported : True
Status : DeviceOk
StatusNote :
DeviceAccessState : Allowed
DeviceAccessStateReason : Global
DeviceAccessControlRule :
DevicePolicyApplied : Default ActiveSync Policy
DevicePolicyApplicationStatus : AppliedInFull
LastDeviceWipeRequestor :
DeviceActiveSyncVersion : 14.1
NumberOfFoldersSynced : 12
SyncStateUpgradeTime :