#LL @ME

Getting AD NetBIOS Name From User DN

(Get-ADDomain (($user.DistinguishedName.Split(",") | ? {$_ -like "DC=*"}) -join ",")).NetBIOSName

SSL Certificate Binding to Process

SSL certificate is usually used in Web Server, IIS for example. Obviously binding an SSL certificate to IIS site is a very straightforward task.

Using IIS Manager, you go to the site


Edit Site Bindings...


Select the https (443)


The select the certificate from the list



Sometime you need to bind SSL certificate to a process or an application. If the application has got an interface or GUI to bind to an SSL certificate, great!. If not, then you need to follow the process here:

Get the application ID, by running WMI query:

wmic product list

This query produces a list of application name, its identifying number and install location


Get the application identifier number (highlighted)

The next step is to get the SSL certificate hash/thumbprint. To get this you can either run:

netsh http show sslcert


or

Get it from the certificate itself


Finally you can bind it using the following command:

netsh http add sslcert ipport=<ip address>:<port> certhash=<cert thumbprint> appid={<app id>}







PowerShell Sorting Hash Table

This is just a quick one, how to sort PowerShell Hash Table:

$ht = @{}
$ht.Add(key1,value1)
$ht.Add(key2,value2)

$ht = $ht.GetEnumerator() | Sort-Object -Descending Value

PowerShell Module Quick Rundown

Yes, you have created PowerShell Script. But you better off converting your PowerShell script to a PowerShell Module.

To create a module, first you need to convert your script to a function. Test the function and when you are ready:

(optional) - Export Function to be exposed to the public
add the following line to the end of your PowerShell Script File
Export-ModuleMember -Function <Function Name>

Save the file as <ModuleName>.psm1
Note: <ModuleName> is the module name

Get the PS Module path
$env:PSModulePath

Go to the PS Module Path
Create a folder EXACTLY the same name with <ModuleName>
Store the <ModuleName>.psm1 to the PS Module Path folder created

Check the Module is now available
Get-Module -ListAvailable

Import Module
Import-Module <ModuleName>

To view command available in the module
Get-Command -Module <ModuleName>

(optional) - To Create Manifest
New-ModuleManifest -Path <Path to the .psd1 new manifest file> -FunctionsToExport <Name of functions to be exported> -Author <Author Name> -CompanyName <Company> - Copyright <Copyright> -ModuleVersion <version#> -Description <Module Description>

Note: Path must be the same location where the actual module file (.psm1) is located

Passed Microsoft Exam 074-409

Today, I passed 074-409 Microsoft Exam: Server Virtualization with Windows Server Hyper-V & System Center. Not bad... what's next I wonder?

Setting Up Hyper-V 2012 R2 Server Core

In the past year or two, I used to have 2 Hyper-V Servers. They are good for hypervisor platform. The best thing I like about having 2 Hyper-V Servers is Replication. I need the replication to make sure my critical virtual machines are available when one of the hosts failed.

Anyway, I decided to shutdown one of the hosts. I still need the replication for my critical virtual machines. My physical host has got a local RAID controller, on which all the virtual machines are running. I decided to create a virtual Hyper-V Server 2012 R2 Core running on this physical host.

Within the virtual Hyper-V server, I initiate iSCSI to my QNAP NAS and set the Hyper-V replication settings to use this iSCSI disk as the target for Hyper-V replication, e.g. all replicated vdisk will be stored in the iSCSI disk

The challenge is to configure Hyper-V server core, which by default has the firewall enabled.
Firstly, I need to enable the firewall for Remote Disk Management. The rules are there, but by default is disabled. We need to find the group on which the rules are specified.

To find the grouping:

Get-NetFirewallRule | Select DisplayGroup -Unique | Sort DisplayGroup


As you can see there is a group called Remote Service Management and Remote Volume Management

 To find the rule within the group:

Get-NetFirewallRule | Where {$_.DisplayGroup -eq "Remote Service Management"} | Select Name


As you can see there are 3 rules associated with the group. To enable them:

Get-NetFirewallRule | Where {$_.DisplayGroup -eq "Remote Service Management"} | Enable-NetFirewallRule

You then need to do the same thing for Remote Volume Management and Hyper-V Replica HTTP

Once you have enabled all the rules, from your physical host, using Server Manager, you can add your Hyper-V Core Server and right click on the server and run Computer Management from the context menu


Now because I would like to run iSCSI initiator from this virtual Hyper-V Core server, I then enable the Microsoft iSCSI Initiator Service and change its startup type to be Automatic

You then need to setup the iSCSI, by running iscsicpl from the command prompt of the Hyper-V Core Server


Enter the details of your iSCSI target and then using the Disk Management you can format and assign a drive letter to the newly created iSCSI disk. Once you have the disk, using Hyper-V Manager, run Hyper-V Settings


Within Hyper-V Settings, select Replication Configuration



Select Enable this computer as a Replica Server, and select either Use Kerberos (HTTP) or Use certificate-based Authentication (HTTPS)



Lastly, specify the default location to store Replica files


You can now start replicating your Virtual Machines!!

Exchange 2013 CU2 v2 Installation Guide

Here are the steps that I have followed to upgrade my Exchange 2013 CU1 servers to CU2 v2 version

I have 1x (MBX + CAS) Server role, 2x MBX Server role and 2x CAS Server role. The order of patching is to have MBX server done first, then CAS server following after that. All the MBX servers I have are a member of the same DAG Cluster

Exchange Schema Version
Exchange 2013 CU2 is upgrading the Active Directory schema as part of the installation.
To check the existing schema version of the Exchange, run the following PowerShell script:


$root  = [ADSI]"LDAP://RootDSE"
$name  = "CN=ms-Exch-Schema-Version-Pt," + $root.schemaNamingContext
$value = [ADSI]( "LDAP://" + $name )
"Exchange Schema Version = $( $value.rangeUpper )"

The CU1 schema version is: 15254

I prefer to run the schema change using the Setup.exe command line rather then using the GUI.
Make sure the server that you are running the schema change is on the same site with the domain controller who holds the schema master FSMO
Make sure the account that you are using to run the schema change is a member of Enterprise Admin group

To run the schema upgrade, using the setup.exe from the extracted CU2 file:


Setup.exe /PrepareSchema /IAcceptExchangeServerLicenseTerms
Setup.exe /PrepareAD /IAcceptExchangeServerLicenseTerms
Setup.exe /PrepareDomain /IAcceptExchangeServerLicenseTerms



After the schema upgrade, the version is: 15281

Exchange Mailbox Role Upgrade
Make sure the PowerShell Script Execution Policy is set to "Unrestricted" before you are starting the upgrade process

Set-ExecutionPolicy Unrestricted

If there is another language pack of UM installed other then en-US, it must be uninstalled (for example if you have en-AU language pack installed):

Setup.exe /RemoveUMLanguagePack:en-AU

If you are using SCOM to monitor this mailbox server, put the agent under maintenance

If you have an active Mailbox database on this server, move it to another server

Drain the Hub Transport

Set-ServerComponentState <servername> -Component HubTransport -State Draining -Requester Maintenance

Redirect Message to another server
Redirect-Message -Server <servername> -Target <target-server.fqdn>
Note: target-server.fqdn MUST be FQDN


Suspend DAG Node
Suspend-ClusterNode -Name <servername>

Disable database copy activation
Set-MailboxServer <servername> -DatabaseCopyActivationDisabledAndMoveNow $true

Review the existing database copy auto activation policy
Get-MailboxServer <servername> | Select DatabaseCopyAutoActivationPolicy
Take a note of the copy auto activation policy **

Set AutoActivation policy to blocked
Set-MailboxServer <servername> -DatabaseCopyAutoActivationPolicy Blocked

Put Server in Maintenance Mode
Set-ServerComponentState <servername> -Component ServerWideOffline -State InActive -Requester Maintenance

Apply CU2 to the server
Run the setup.exe from the CU2 extracted folder
Once finished, reboot the server

Stop DAG Maintenance mode
Set-ServerComponentState <servername> -Component ServerWideOffline -State Active - Requested Maintenance

Resume DAG node
Resume-ClusterNode -Name <servername>

Set AutoActivation policy to original setting
Set-MailboxServer <servername> -DatabaseCopyAutoActivationPolicy Unrestricted (** original settings from the above command)

Enable database copy activation
Set-MailboxServer <servername> -DatabaseCopyActivationDisabledAndMoveNow $false

Put Server in Active Mode
Set-ServerComponentState <servername> -Component HubTransport - State Active -Requested Maintenance

- Re-install Language Pack if needed
- Take server out of maintenance mode in SCOM


Exchange CAS Role Upgrade
Make sure the PowerShell Script Execution Policy is set to "Unrestricted" before you are starting the upgrade process

If you are using SCOM to monitor this mailbox server, put the agent under maintenance


Apply CU2 to the server
Run the setup.exe from the CU2 extracted folder
Once finished, reboot the server


- Take server out of maintenance mode in SCOM

Exchange 2010 Mailbox Restore with NetBackup 7.5.6

Today, I needed to restore a mailbox from Exchange 2010 from NetBackup.
Here is the steps I did to get it done:

Create a Recovery Database

Add a storage to the exchange server (e.g. virtual disk to the VM)
Assign a drive letter to this newly created disk in the exchange server (e.g. Z: drive)
Create a folder for the recovery DB (e.g. Z:\Recovery)
Create a folder for the recovery log (e.g. Z:\Recovery\Log)

Run the PowerShell below to create a recovery DB:

New-MailboxDatabase -Recovery -Name recoveryDB -Server exc01 -EdbFilePath ”Z:\Recovery\Mailbox01.edb” -LogFolderPath “Z:\Recovery\Log”

I make the EDB file name exactly the same file name with the original EDB file

On the properties of the recoveryDB, make sure the "This database can be overwritten by a restore" is selected



Restore the Database Backup

From the Netbackup Console, Add the client: File - Specify NetBackup Machines and Policy Type...
Click on Edit Client List button
Add the client name
Source client for restores: exc01
Destination client for restores: exc01
Policy type for restores: MS-Exchange-Server

Select the date of the backup to be restored


Navigate to the Microsoft Information Store and select both database and log


Click the restore icon
On Microsoft Exchange tab: 
Point-in-Time Recovery (Replay only restored log files)
Commit after last backup set is restored



On General tab:
Restore everything to a different location (maintaining existing structure)
Destination: Microsoft Exchange Database Availability Groups:\dag\Microsoft Information Store\RecoveryDB\

Note: Make sure the Destination is RecoveryDB



Click Start Restore

Mount the Database

Once the restore is completed, mount the RecoveryDB (if not mount automatically)

Create a Recovery Account

Create a recovery account for mailbox (target)
Run the PowerShell to restore the mailbox

Restore-Mailbox -Identity recoveryUser -RecoveryDatabase RecoveryDB -RecoveryMailbox sourceMailboxUser -TargetFolder Recovery

Changing Network Location on Windows 2008R2/2012

For some unknown reason, one of my domain controller servers has changed its network location from domain to public:

This is annoying because the 'public domain' firewall then starts blocking all unknown incoming traffic to my server.
We need to change this network location to be domain. However sometime, the location name is not clickable!!

To fix this, I found a trick:
Navigate to this network properties and un-tick the Internet Protocol Version 6 (TCP/IPv6) stack


Click OK

Then it should change the network location type to domain
Now you can change the IPv6 stack back ON

Configuration File is not well-formed XML

Today, I found one of my Exchange 2013 servers start generating Event ID 2001


It turns out that Exchange has corrupted the applicationHost.config file. If you try to open the file, you will see corrupted garbage characters all over the place.

Luckily I have got another Exchange 2013 server running on DAG, so I just copy the file applicationHost.config from C:\Windows\System32\inetsrv\config folder and replace the corrupted one then do IIS Reset

Pass 70-413 Exam

Just pass 70-413 exam today! Next one will be 70-414

Micro$oft, what the.... ???

Got these a lot on my server for the last 4 days:

The IP 157.56.162.105 has just been banned by Fail2Ban after
6 attempts against ssh.

Here are more information about 157.56.162.105:

Lines containing IP:157.56.162.105 in /var/log/auth.log

Aug 11 20:40:08 x sshd[60929]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=157.56.162.105  user=root
Aug 11 20:40:10 x sshd[60929]: Failed password for root from 157.56.162.105 port 62640 ssh2
Aug 11 20:40:10 x sshd[60929]: Received disconnect from 157.56.162.105: 11: Bye Bye [preauth]
Aug 11 20:40:18 x sshd[60931]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=157.56.162.105  user=root
Aug 11 20:40:20 x sshd[60931]: Failed password for root from 157.56.162.105 port 1112 ssh2
Aug 11 20:40:20 x sshd[60931]: Connection closed by 157.56.162.105 [preauth]
Aug 11 20:50:17 x sshd[60935]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=157.56.162.105  user=root
Aug 11 20:50:18 x sshd[60935]: Failed password for root from 157.56.162.105 port 1064 ssh2
Aug 11 20:50:19 x sshd[60935]: Received disconnect from 157.56.162.105: 11: Bye Bye [preauth]
Aug 11 20:50:21 x sshd[60937]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=157.56.162.105  user=root
Aug 11 20:50:23 x sshd[60937]: Failed password for root from 157.56.162.105 port 62560 ssh2
Aug 11 20:50:23 x sshd[60937]: Received disconnect from 157.56.162.105: 11: Bye Bye [preauth]
Aug 11 20:50:29 x sshd[60939]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=157.56.162.105  user=root
Aug 11 20:50:31 x sshd[60939]: Failed password for root from 157.56.162.105 port 1184 ssh2
Aug 11 20:50:31 x sshd[60939]: Received disconnect from 157.56.162.105: 11: Bye Bye [preauth]
Aug 11 21:00:34 x sshd[60943]: Connection closed by 157.56.162.105 [preauth]

and guess who owns the 157.56.162.105?



MCSA 2012

Yay! just passed Microsoft Exam 70-417 and officially MCSA 2012

Active Directory Domain Controller GPO Reset

I have these 2x Windows 2012 Domain Controllers that inherited policies from the old GPO which were created since Windows 2003 days. I did not realize there were problems until some of the features that I want to use started acting badly (e.g. access denied, etc).

Obviously the DCs have been joined to the domain and be put in the "Domain Controllers" OU by default after they were dcpromo-ed, which then got the old GPO applied to them.

So to clean them up all the registries, file systems security configuration that have been applied to DC, I need to reset the default domain policy and the default domain controllers policy. Before I do that, I back them up first, just in case.

To clean up the GPO run the following command:

C:\> DCGPOFIX

Then I need to clean up the actual settings that have been applied to my DCs by running the following command on each DC:

C:\> secedit /configure /cfg C:\windows\inf\defltdc.inf /db defltdc.sdb /overwrite

Reboot the DC

Manage Workgroup Servers with SCOM 2012

This is a very high level steps how to have your workgroup servers to be managed by SCOM 2012.
I have this task to have my Exchange Edge Transport server sitting on DMZ to be managed by SCOM

For them to be able to communicate and authenticate each other, they must be using a certificate.
I have my internal CA (lucky me)

1. Make sure your Workgroup server trusts your CA.
You can browse to your https://internal-ca.domain.com/certsrv URL and download the CA certificate and import this to the Workgroup server's Trusted Root CA (Computer store)

2. Make sure you have a certificate template that has Server and Client Authentication purposes 
If you don't have one, duplicate one from the "Computer" template with Windows 2003 version. Make sure "allow export private key" is selected and "subject name" is supplied in the request.

3. Request a certificate from your Workgroup server to your internal CA 
Use the template you created on step 2

4. Move certificate from user store to computer store 
After request the certificate, it will automatically install the certificate on the user store. You need to export this (along with the private key) and import it back to the computer store

5. Install SCOM 2012 Agent 
Insert SCOM installation ISO/DVD and install SCOM Agent. Make sure you are using FQDN for the SCOM server during the installation wizard

6. Firewall port need to be allowed on TCP 5723 inbound and outbound 
SCOM Agent is using TCP 5723 port number to communicate with SCOM Server, open this on your firewall inbound and outbound

7. Import the certificate to SCOM Agent
On the installation ISO/DVD, navigate to SupportTools\AMD64 and run MOMCertImport.exe. It then asks you to select which certificate to use. Select the one that you created on step 3

8. Restart the System Center Management service

9. Request a certificate from your SCOM Management Server
Do exactly the same thing like step 3-4, but now do this from the SCOM Management Server

10. Import the certificate to SCOM Management Server
Do exactly the same thing like step 7-8, but now do this from the SCOM Management Server

11. Wait
Your agent should come out on the Pending Management section of your SCOM Administration console

Exchange 2010 SP2 RU 4v2 Bug - Mailbox Move

After applying the SP2 RU 4v2 to my Exchange 2010 environment, apparently there is a bug when a mailbox is moved between two different databases within the same server. According to Microsoft forum this bug was introduced by SP2 RU3. Anyone who is still running on SP2 RU2 is not affected.

When you move the mailbox, it will have the Move Request Status: Completed with warning
You also will get the following comment:

Warning: Failed to clean up the source mailbox after the move.
Error details: MapiExceptionUnexpectedMailboxState: Unable to delete mailbox. (hr=0x80004005, ec=2634)


In the log of the move request, you will see the error:

Failed to clean up the source mailbox 'Primary (9105c233-5387-47bc-99ea-2c0255cf63ad)' after the move. Attempt 1/6.
Error details: MapiExceptionUnexpectedMailboxState MapiExceptionUnexpectedMailboxState: Unable to delete mailbox. (hr=0x80004005, ec=2634) at Microsoft.Mapi.MapiExceptionHelper.ThrowIfError(String message, Int32 hresult, SafeExInterfaceHandle iUnknown, Exception innerException)
   at Microsoft.Mapi.ExRpcAdmin.DeletePrivateMailbox(Guid guidMdb, Guid guidMailbox, Int32 flags)
   at Microsoft.Exchange.MailboxReplicationService.LocalMailbox.DeleteMailboxInternal(Int32 flags)
   at Microsoft.Exchange.MailboxReplicationService.MailboxWrapper.<>c__DisplayClass2a.<Microsoft.Exchange.MailboxReplicationService.IMailbox.DeleteMailbox>b__29()
   at Microsoft.Exchange.MailboxReplicationService.ExecutionContext.Execute(GenericCallDelegate operation)
   at Microsoft.Exchange.MailboxReplicationService.MailboxWrapper.Microsoft.Exchange.MailboxReplicationService.IMailbox.DeleteMailbox(Int32 flags)
   at Microsoft.Exchange.MailboxReplicationService.MoveBaseJob.<>c__DisplayClass6d.<PostMoveCleanupSourceMailbox>b__6b()
   at Microsoft.Exchange.MailboxReplicationService.CommonUtils.CatchKnownExceptions(GenericCallDelegate del, FailureDelegate failureDelegate)


...
...

Post-move cleanup failed. The operation will try again in 30 seconds (5/6).
Failed to clean up the source mailbox 'Primary (9105c233-5387-47bc-99ea-2c0255cf63ad)' after the move. Attempt 6/6.
Error details: MapiExceptionUnexpectedMailboxState MapiExceptionUnexpectedMailboxState: Unable to delete mailbox. (hr=0x80004005, ec=2634)
   at Microsoft.Mapi.MapiExceptionHelper.ThrowIfError(String message, Int32 hresult, SafeExInterfaceHandle iUnknown, Exception innerException)
   at Microsoft.Mapi.ExRpcAdmin.DeletePrivateMailbox(Guid guidMdb, Guid guidMailbox, Int32 flags)
   at Microsoft.Exchange.MailboxReplicationService.LocalMailbox.DeleteMailboxInternal(Int32 flags)
   at Microsoft.Exchange.MailboxReplicationService.MailboxWrapper.<>c__DisplayClass2a.<Microsoft.Exchange.MailboxReplicationService.IMailbox.DeleteMailbox>b__29()
   at Microsoft.Exchange.MailboxReplicationService.ExecutionContext.Execute(GenericCallDelegate operation)
   at Microsoft.Exchange.MailboxReplicationService.MailboxWrapper.Microsoft.Exchange.MailboxReplicationService.IMailbox.DeleteMailbox(Int32 flags)
   at Microsoft.Exchange.MailboxReplicationService.MoveBaseJob.<>c__DisplayClass6d.<PostMoveCleanupSourceMailbox>b__6b()
   at Microsoft.Exchange.MailboxReplicationService.CommonUtils.CatchKnownExceptions(GenericCallDelegate del, FailureDelegate failureDelegate)
 

Request is complete.

The implication of this bug:
  • There will be delay of 30 seconds x 6 tries = 3 minutes for each mailbox being moved
  • During the last 3 minutes of the mailbox move, the Outlook client is being disconnected
  • Mailbox in the source database is not deleted, it is mark as soft deleted mailbox
 To view the Soft Deleted mailboxes:

Get-MailboxDatabase | Get-MailboxStatistics | where {$_.DisconnectReason -ne $null} | ft  displayname,database,disconnectreason -auto

To delete the Soft Deleted mailboxes:

Remove-StoreMailbox -database "Old database" -Identity "Smith, John" -MailboxState SoftDeleted

So far there is no report from my users who have got their mailboxes moved


DNS IP to localhost

While I am doing this coding of DNS server and using my development machine to debug the program, I need to somehow configure my Windows 7 client's DNS setting to point to itself as the DNS server (e.g. 127.0.0.1).

Surprisingly, Windows 7 rejects the setting when you put 127.0.0.1 as the DNS IP address of your network connection.

Found the following Powershell to change it easily

$wmi = Get-WmiObject win32_networkadapterconfiguration -filter "ipenabled = 'true'"
$wmi.SetDNSServerSearchOrder("127.0.0.1")

SSRS SQL 2008 R2 Export Reports

I need to migrate reports from the old SSRS to the new one. To do this, I need to export all the reports as an RDL file and upload them all to the new SSRS server

Found this article by geektrainer.com how to create a VB script .rss file to exports all SQL Server Report file as an .rdl file.

Here is the code:

'must use -v rootPath="C:\Reports"
Sub Main()    
    Dim items As CatalogItem() = rs.ListChildren("/", true)

    For Each item As CatalogItem in items
        If item.Type = ItemTypeEnum.Folder Then
            CreateDirectory(item.Path)
        Else If item.Type = ItemTypeEnum.Report Then
            SaveReport(item.Path)
        End If
    Next
End Sub

Sub CreateDirectory(path As String)
    path = GetLocalPath(path)
    System.IO.Directory.CreateDirectory(path)
End Sub

Sub SaveReport(reportName As String)
    Dim reportDefinition As Byte()
    Dim document As New System.Xml.XmlDocument()
    
    reportDefinition = rs.GetReportDefinition(reportName)
    
    Dim stream As New MemoryStream(reportDefinition)
    document.Load(stream)
    document.Save(GetLocalPath(reportName) + ".rdl")
End Sub

Function GetLocalPath(rsPath As String) As String
    Return rootPath + rsPath.Replace("/", "\")
End Function

Save the code below as export.rss file, create a folder where the reports will be stored (e.g. C:\Reports) then run the RS.EXE command against your report server web service URL

rs.exe -i export.rss -s http://reportserver.domain.local/ReportServer -v rootPath="C:\Reports"

This will create all the reports in the .rdl format in the folder specified above



Windows Vault - SharePoint 2010

I have seen a problem where a user always prompts for a username and password when they are trying to open a SharePoint 2010 site. The credential dialog box has got the username field as READ ONLY.

The reason for the prompt is that the username for unknown reason is wrong and cannot be changed!

If you check the security event log, you will see Event ID 4648

To fix this problem you need to check the Windows Credential Manager, start it from the CMD

control /name Microsoft.CredentialManager


and remove the wrongly assigned credential to the site

App-V SQL Move Error 0000C800

Recently I just moved App-V SQL Database from one to the other. I use the following procedures:

http://technet.microsoft.com/en-us/library/gg252515.aspx

However, when trying to open the management console, I got the error code: 0000C800
One of the troubleshooting I have done was changing the UDL file and test connection was working, however the error persists.

It ended up I have to do the followings:

  • Open the SftMgmt.udl file from the Notepad
  • Copy the content of the file
  • Rename the SftMgmt.udl file to SftMgmt.udl.old
  • Create a new file using Notepad
  • Paste the connection string to the newly created file and modify the connection string to use the new SQL name
  • Save as the file to SftMgmt.udl
  • DO NOT open this newly created file. Try to open the management console again, if that works, job is done!