PowerShell: 135
===

Someone who understands RegEx better than I might be able to help trim this a bit.

**Gofled Code**

    for(;($x-cmatch'[a-z]')+($x-cmatch'[A-Z]')+($x-match'\d')+($x-match'[!-/:-@\[-`{-~]')-ne4){$x='';1..15|%{$x+=[char](33..126|random)}}$x

**Un-golfed and Commented**

    # Start a for loop.
    for(
        # Skip variable initialization, start definition of run condition.
        ;(
            # Check if $x has a lowercase character.
            $x-cmatch'[a-z]'
        )+(
            # Check if $x has an uppercase character.
            $x-cmatch'[A-Z]'
        )+(
            # Check if $x has a number.
            $x-match'\d'
        )+(
            # Check if $x has one of the required symbols.
            $x-match'[!-/:-@\[-`{-~]'
        # Run the script block if $x does not have all 4 character types included.
        )-ne4
    )
    {
        # Reset $x in case the script block has already run.
        $x='';
        # Use ForEach-Object, via the % alias, to run a loop 15 times.
        1..15|%{
            # Append a random ASCII character from 33-126 to $x.
            $x+=[char](33..126|random)
        }
    }
    # Display $x.
    $x
    # Variable cleanup - not included in golfed code.
    rv x