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

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
}

Related

Loading .msg file contents Using Powershell - Null Value error

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

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 ?

Why can't I change `Real Time Monitoring` parameter value in powershell?

I am learning how to use PowerShell to control a Windows 10 VM for pentesting purposes, the cmdlet Get-MpPreference has so many parameters the ones I am interested in are
DisableIntrusionPreventionSystem :
DisableIOAVProtection : False
DisablePrivacyMode : False
DisableRealtimeMonitoring : False
DisableRemovableDriveScanning : True
DisableRestorePoint : True
DisableScanningMappedNetworkDrivesForFullScan : True
DisableScanningNetworkFiles : False
Now when I type set-mppreference -DisableRealtimeMonitoring $True I expected that parameter to have a value of Ture but I does not change.
I am running PowerShell as an admin

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?

How many status of azure deployment could be

All, I am trying to deploy my cloud service to Windows Azure. Currently It works fine. But I still try to understand the detail inside of it . Like below Power Shell script.
The script is trying to get the status of a deplpoyment in the Staging slot after New-AzureDeployment has been executed successfully.
while ($True) {
$deployment = Get-AzureDeployment -ServiceName $CloudServiceName -Slot Staging
if ($deployment.Status -ne 'Running') {
continue
}
$notReadyList = $deployment.RoleInstanceList | Where-Object InstanceStatus -ne 'ReadyRole'
if (!$notReadyList) {
break
}
$errorStatusList = #('RestartingRole';'CyclingRole';'FailedStartingRole';'FailedStartingVM';'UnresponsiveRole')
$errorList = $notReadyList | Where-Object InstanceStatus -in $errorStatusList
if ($errorList) {
throw 'Role in staging fail to start for some of these reasons:' + ($errorList | Format-List | Out-String)
}
Start-Sleep -Seconds 10
}
I have some questions about the script . Please try to help me .thanks.
What is the object type of Get-AzureDeployment return ? I search it in the Help Doc. But did't found any information about it.
How many possible status except Running the Get-AzureDeployment could return ?
Is there any possibility never break in the loop ?
Thanks.
What is the object type of Get-AzureDeployment return ? I search it in
the Help Doc. But did't found any information about it.
As mentioned in the documentation, this operation returns an object of type DeploymentInfoContext. You can find more about this object here: https://github.com/WindowsAzure/azure-sdk-tools/blob/master/WindowsAzurePowershell/src/Commands.ServiceManagement/Model/DeploymentInfoContext.cs. However if you look at the source code for Get-AzureDeployment here: https://github.com/WindowsAzure/azure-sdk-tools/blob/master/WindowsAzurePowershell/src/Commands.ServiceManagement/HostedServices/GetAzureDeployment.cs, you'll notice that it returns the following:
return new DeploymentInfoContext(d)
{
OperationId = s.Id,
OperationStatus = s.Status.ToString(),
OperationDescription = CommandRuntime.ToString(),
ServiceName = this.ServiceName
};
How many possible status except Running the Get-AzureDeployment could
return ?
You can find the list of possible statuses here: http://msdn.microsoft.com/en-us/library/windowsazure/ee460804.aspx.
Following is copied from the link above:
Is there any possibility never break in the loop ?
I'm not sure about that. I guess you will need to test it out thoroughly. The statuses may change with the newer versions of Service Management API so you would need to ensure that your code covers all possible statuses.
Get-AzureDeployment returns an object of schema shown below
SdkVersion :
RollbackAllowed : False
Slot : Production
Name :
DeploymentName : [Somename]
Url : http://[Somename].cloudapp.net/
Status : Suspended
CurrentUpgradeDomain : 0
CurrentUpgradeDomainState :
UpgradeType :
RoleInstanceList : {}
Configuration :
DeploymentId : [SomeGUID]
Label : [Somename]
VNetName : [Somename]
DnsSettings :
OSVersion :
RolesConfiguration : {[[Somename], Microsoft.WindowsAzure.Commands.ServiceManagement.Model.RoleConfiguration]}
ServiceName : [Somename]
OperationDescription : Get-AzureDeployment
OperationId : 1801bce8-73b4-5a74-9e80-e03d04ff405b
OperationStatus : Succeeded